Running pgc++ programs on Cluster - c++

I tried to run the below OPenACC program on cluster:
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
#pragma acc parallel loop
for (int i=0; i<1000; i++)
{
//cout << i << endl;
printf("%d ", i);
}
return 0;
}
The PBS Script for the above code:
#PBS -e errorlog1.err
#PBS -o logfilehello.log
#PBS -q rupesh_gpuq
#PBS -l select=1:ncpus=1:ngpus=1
tpdir=`echo $PBS_JOBID | cut -f 1 -d .`
tempdir=$HOME/scratch/job$tpdir
mkdir -p $tempdir
cd $tempdir
cp -R $PBS_O_WORKDIR/* .
module load nvhpc-compiler
#module load cuda10.1
#module load gcc10.3.0
#module load nvhpc-21.11
#module load nvhpc-pgicompiler
#module load gcc920
pgc++ sssp.cpp
./a.out > output.txt
rm *.out
mv * $PBS_O_WORKDIR/.
rmdir $tempdir
~
After submmitting the above job to que, I get the following error log:
"sssp.cpp", line 2: catastrophic error: cannot open source file "iostream" #include <iostream>
^
1 catastrophic error detected in the compilation of "sssp.cpp". Compilation terminated.
I tried running C programs on pgcc and they work fine. Running c++ programs on pgc++ is throwing error. What could be the reason?

What could be the reason?
In order to be interoperable with g++, pgc++ (aka nvc++) uses the g++ STL and system header files. Since the location of these headers can vary, on installation a configuration file, "localrc", is created to store these locations.
What could be happening here is that on install, a single system install was selected and hence the generated localrc is for the system from which the compilers were installed, not the remote system.
If this is the case, consider re-installing with the "network" option. In this case, the creation of the localrc is delayed until the first compiler invocation with a unique localrc generated for each system.
Another possibility is that creating of the localrc file failed for some unknown reason. Possibly a permission issue. To check, you can run the 'makelocalrc' utility to see if any errors occurred.
Note for newer versions of nvc++, we are moving away from using pre-generated config files and instead determining these config items each time the compiler is invoked. The pervious concern being the overhead involved in generating the config, but this has become less of a problem.

Related

Include Git commit hash and/or branch name in C/C++ source

I would like to know how you can get a Git commit hash and/or other information into the contents of a C++ variable in the compiled binary without having it be part of the source that's tracked by Git.
I need to keep track of firmware release information in a compiled executable running on an embedded processor. Means to identify the particular release of the firmware binary such as meaningful filenames, MD5 checksums or even date/time stamps are not available in this closed environment (i.e., there is no filesystem).
One approach is to have the device's console output produce identifying text, such as 'Release 1.2.3', 'commit hash 1bc123...', or similar. The firmware release information is only of interest to maintenance personnel, so a trained operator could examine the console output. To implement this it could potentially involve manual editing of a version string, which is then compiled into the code and output to the console at program startup.
This is acceptable for major releases where a signoff workflow is used to double-check that the version information is correct. However, this being a manual process it is inherently unreliable. For example, what if the developer forgets to update the version information? - There is now a disconnect between the compiled code and its reported version string.
A workflow where the code is freshly compiled and downloaded each time the user wants to test the hardware is not practical in the situation in question, ie., it is quite onerous to update the firmware.
An automatic way of identifying the version of the code is thus required. In the situation in question, Git is used, and the developers regularly commit their work to feature branches. Displaying the Git commit hash, and perhaps also whether or not there are unstaged changes, would be a way of identifying the status of the source code used to compile the firmware.
The requirement is that I would like my application to have information available to it so that it is able to display:
"Git commit:[01abcdef...etc], branch: experimentalStuffDoNotRelease"
Thus, I would like to automatically include Git information, such as commit hash and branch, in the compiled C and/or C++ code.
The development environment has developers using both Windows and Linux, and uses Eclipse CDT with a relatively unsophisticated workflow of: check out; compile; download to the hardware.
I use a makefile, like so:
GIT_HASH=`git rev-parse HEAD`
COMPILE_TIME=`date -u +'%Y-%m-%d %H:%M:%S UTC'`
GIT_BRANCH=`git branch | grep "^\*" | sed 's/^..//'`
export VERSION_FLAGS=-DGIT_HASH="\"$(GIT_HASH)\"" -DCOMPILE_TIME="\"$(COMPILE_TIME)\"" -DGIT_BRANCH="\"$(GIT_BRANCH)\""
all:
g++ main.cpp $(VERSION_FLAGS)
When the makefile is run, the git hash and the time of compilation are both loaded into macros accessible within the source, like so:
#include <iostream>
int main(){
std::cerr<<"hash="<<GIT_HASH<<", time="<<COMPILE_TIME<<", branch="<<GIT_BRANCH<<std::endl;
}
Which gives output like:
hash=35f531bf1c959626e1b95f2d3e1a7d1e4c58e5ec, time=2017-05-18 04:17:25 UTC, branch=master
In Eclipse CDT, use a pre-build step to generate an include file containing the relevant information, and a conditional inclusion to check that the file was created:
Right-click the project
Select Properties
Expand the C/C++ Build
Select Settings In the Build Steps tab
Enter the following in the Command text box:
git log --pretty=format:'#define GIT_INFO_PRESENT%n static const char* GIT_INFO = "Version Information=[%H,%d]\r\n";' -n 1 > ../src/gitcommit.h
This will, upon build, create a file gitcommit.h that will be included in the source code. To customise it, adjust the string to your needs. (See https://git-scm.com/docs/pretty-formats)
As an example, I produce a debug output at the beginning of the main routine to inform the user of the commit and branch (not strictly needed knowing the commit, but certainly helpful):
Put this in the file, probably at the top
#if __has_include("gitcommit.h")
#include "gitcommit.h"
#else
static const char* GIT_INFO = "Git version information not present.\r\n";
#endif
To display the information somewhere in your code, do similar to this:
printf(GIT_INFO);
Note that I haven't, in this case, made the pre-build step a shell script or Windows/DOS .bat file, as I work often in Linux or Windows.
Note that this isn't tested in Windows.
In both cases, 'git' must be executable from the standard command line.
There is a dependency on provision of __has_include. This was intended to provide simplicity so that a default include file need not be provided.
Note that the gitcommit.h file's path should be discoverable by the compiler.
Usually as part of your build you run some command that generates something like that.
For example, git describe gives you something that you could use:
echo // auto generated version: > version.h
git describe > echo // auto generated version: > version.h
echo -e "#define VERSION " >> version.h
git describe >> version.h
For example x264 use this simple script to generate it:
if [ -d .git ] && command -v git >/dev/null 2>&1 ; then
localver="$(($(git rev-list HEAD | wc -l)))"
if [ "$localver" -gt 1 ] ; then
ver_diff="$(($(git rev-list origin/master..HEAD | wc -l)))"
ver="$((localver-ver_diff))"
echo "#define X264_REV $ver"
echo "#define X264_REV_DIFF $ver_diff"
if [ "$ver_diff" -ne 0 ] ; then
ver="$ver+$ver_diff"
fi
if git status | grep -q "modified:" ; then
ver="${ver}M"
fi
ver="$ver $(git rev-list -n 1 HEAD | cut -c 1-7)"
version=" r$ver"
fi
fi
echo "#define X264_VERSION \"$version\""
echo "#define X264_POINTVER \"0.$ver\""
This will generate something like:
#define X264_VERSION " r2708 86b7198"
#define X264_POINTVER "0.148.2708 86b7198"
Here's simple solution if you need git hash and local modifications flag only:
$ cat update-version-info.sh
#!/bin/sh
version=$(git describe --always --dirty --tags)
echo "#define GIT_VERSION \"$version\"" > git-version.h
$ cat 1.c
#include <stdlib.h>
#include <stdio.h>
#include "git-version.h"
int main() {
#ifdef GIT_VERSION
printf("%s\n", GIT_VERSION);
#endif
return 0;
}
$ ./1
ee4f307-dirty
Based on #Richard's answer and my fixes for qmake/Qt, here is the solution I use:
With Qt 5.14 the following lines in .pro file work for me:
GIT_HASH="\\\"$$system(git -C \""$$_PRO_FILE_PWD_"\" rev-parse --short HEAD)\\\""
GIT_BRANCH="\\\"$$system(git -C \""$$_PRO_FILE_PWD_"\" rev-parse --abbrev-ref HEAD)\\\""
BUILD_TIMESTAMP="\\\"$$system(date -u +\""%Y-%m-%dT%H:%M:%SUTC\"")\\\""
DEFINES += GIT_HASH=$$GIT_HASH GIT_BRANCH=$$GIT_BRANCH BUILD_TIMESTAMP=$$BUILD_TIMESTAMP
In your code you can check the revision like this:
int main(int argc, char *argv[])
{
QStringList args;
for (int i = 0; i < argc; i++)
args << QString(argv[i]);
if (args.contains("-v") || args.contains("--version")) {
std::cout << QString("branch: %1, version: %2, built_at: %3").arg(GIT_BRANCH).arg(GIT_HASH).arg(BUILD_TIMESTAMP).toUtf8().constData() << std::endl;
return 0;
}
// ...
}
A C file or a C++ file can be generated by some program (for example, some shell script on Linux, or some GNU awk script, or your C program running system or popen(3) running some git command).
You just configure your build automation tool (e.g. your Makefile if you use GNU make, or your build.ninja file if you use ninja) appropriately.
Both Bismon and RefPerSys are doing so and keep their git id inside the obtained executable (displaying it when invoked with --version). Note: both are projects I created.
PS a different question is how to configure your IDE to run a particular build automation tool. This is specific to your IDE. But Eclipse CDT FAQ offers an insight.

Startup program and libocci.so.11.1: cannot open shared object file: No such file or directory

please any one save my time .my application is written in c++ I was try to startup on boot in ubuntu linux,but when the program try to start it log error like:-
error while loading shared libraries: libocci.so.11.1: cannot open shared object file: No such file or directory
my program use oracle api:-
my start service script which is written in /etc/init.d/sistartup:-
#!/bin/sh
# chkconfig: 345 99 10
OWNER=aki
case "$1" in
'start')
su $OWNER -c "/home/aki/sis_script/startsis.sh >> /home/aki/sis_script/sistartup.log 2>&1" &
# touch /var/lock/subsys/sis_engine
;;
esac
startup script which is written on appropriate user is:-
/home/aki/script/startsis.sh
#!/bin/bash
export TMP=/tmp
export TMPDIR=$TMP
export PATH=/usr/sbin:/usr/local/bin:$PATH
# Start db_test
./home/aki/summ/db_test
My c++ sample test_db.cpp application write below:-
#include <iostream>
#include <occi.h>
#include <string>
using namespace oracle::occi;
using namespace std;
Environment *env;
Connection *con;
int main(){
string user;
string passwd;
string db;
user ="sis";
passwd = "sis10";
db = "localhost:1521/sisdba";
env = Environment::createEnvironment((Environment::Mode)(Environment::OBJECT|Environment::THREADED_MUTEXED));
con = env->createConnection(user, passwd, db);
while(1){
cout<<"Here i have some business which is related to oracle database "<<endl;
}
return 0;
}
After compiling the file in this way
g++ -o db_test test_db.cpp -I$ORACLE_HOME/rdbms/public -L$ORACLE_HOME/lib -locci -lclntsh
I see this error :-
error while loading shared libraries: libocci.so.11.1: cannot open shared object file: No such file or directory
If you have to provide -L$ORACLE_HOME/lib on the build command line, that suggests to me that the libraries aren't in any of the system's library paths, so they won't be found automatically at runtime.
You can confirm this theory by setting LD_LIBRARY_PATH=$ORACLE_HOME/lib before running your program; it should then work. However, depending on your requirements, this may be only worth a temporary workaround (and I'm assuming the $ORACLE_HOME is available!). A more long-term fix might be to add this path to /etc/ld.so.conf, though this then will affect all executables on your system.
Ultimately, you should follow the installation instructions for the library.
did libocci.so.11.1 successfully installed?

C++ Mingw32 CreateProcess() failed with error code 2: The system cannot find the file specified

I am just trying to run a basic program in notepad++ and mingw32. I have attempted multiple different thing but I continue to get.
Current directory: \\THEBOX\Users\jacks_000\Documents
C:\MinGW\mingw32\bin\g++.exe -g "testpgrm"
CreateProcess() failed with error code 2:
The system cannot find the file specified.
================ READY ================
When I run the nppexec I use the following
NPP_SAVE
CD $(CURRENT_DIRECTORY)
C:\MinGW\mingw32\bin\g++.exe -g "$(FILE_NAME)"
I have also tried:
NPP_SAVE
CD $(CURRENT_DIRECTORY)
C:\MinGW\bin\g++.exe -g "$(FILE_NAME)"
I am just using a basic test program:
#include <iostream>
using namespace std;
int main()
{
cout<<"Hi";
return 0;
}
I don't know if I will have issue running it in the command prompt if I save it this way or if I have done something wrong. I am running Windows 10 if that is a issue.
Current directory: \THEBOX\Users\jacks_000\Documents
I think it's because g++ can't access to a SMB share.
Try to compile the file locally.
The problem is with the location of "C:\MinGW\mingw32\bin\g++.exe". Where it is on your PC, and what is the actual filename, will depend on your installation.
For example, on my machine I have and old version in "C:\Program Files (x86)\CodeBlocks13_02\MinGW\bin\mingw32-g++.exe", but a newer installation in another folder.
So you need to find the executable name and location of the compiler. You won't need to use the top two lines, just "C:\Program Files (x86)\CodeBlocks13_02\MinGW\bin\mingw32-g++.exe -g test.c", for example.
I did this and it gave a result of :
C:\Program Files (x86)\CodeBlocks13_02\MinGW\bin\mingw32-g++.exe -g test.c
Process started >>>
<<< Process finished. (Exit code 0)
================ READY ================

"Operation not permitted" running hello world binary compiled w/ clang++ on El Capitan

Background
I created a simple Hello World C++ program:
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!" << endl;
return 0;
}
And compiled it with clang++ like so (g++ points to clang++ on OS X apparently):
g++ helloworld-cpp.cpp
This produces an executable, a.out. Running it at the prompt causes bash to throw the error Operation not permitted, as shown:
$ ./a.out
-bash: ./a.out: Operation not permitted
Things I've Tried
Verifying the file has execute permissions, and no attributes or flags that would prevent it from running, using ls -leO:
-rwxr-xr-x 1 monarch staff - 15212 Jan 1 13:51 a.out
Disabling "System Integrity Protection" using csrutil disable from the Recovery OS terminal, rebooting, recompiling, and running a.out. The same error messages results.
Question
Are there any other restrictions that could prevent binaries I compile on Mac OS X from running?
Figured it out.
My code was on an encrypted sparseimage, which had the quarantined attribute set on it. I checked this by running mount like so (see attributes on /Volumes/work):
$ mount
/dev/disk0s2 on / (hfs, local, journaled)
/dev/disk2s2 on /Volumes/work (hfs, local, nodev, nosuid, journaled, noowners, quarantine, mounted by monarch)
The actual sparseimage is located in my home folder, titled work.sparseimage. I removed the quarantine attribute like so:
$ xattr -d com.apple.quarantine work_personal.sparseimage
I then unmounted (ejected) the image, then re-mounted it, recompiled the file and it executed without the error.
Special thanks to #Mark Setchell for asking me in the question's comments if noexec was set on the drive, and to everyone else for their suggestions.

Why does the behavior of mkdir differs on different Linux distros?

I was trying to create folders named 1 2 3 4, using the C++ program below. I can successfully achieve that in RHEL.
However it created a folder named {1..4} in ubuntu 13.10.
Why does this happen? Thank you for helping me!
#include <cstdlib>
int main()
{
std::system("mkdir {1..4}");
}
It's a part of CPP unit test in our product. Yes, it's ugly. But I am afraid very few thing can be done in this situation.
You are right.
In RHEL,
sh -c 'echo {1..4}'
1 2 3 4
In Ubuntu
sh -c 'echo {1..4}'
{1..4}
So I use the program below instead. It works!
#include
int main()
{
std::system("bash -c 'mkdir {1..4}'");
}
seems system use sh by default....Thank you for your answer!
A bit of terminology: Linux has directories in its file systems, not "folders" (folders may appear visually on the desktop, but that is a desktop detail).
You don't need to use system(3) (which is running sh not bash!).
And POSIX sh don't know the {1..4} notation, hence the {1..4} string is passed verbatim to /bin/mkdir command (see mkdir(1) ...).
Run
sh -c 'echo {1..4}'
to test that sh don't understand the {1..4} notation.
(so it is a bug in your old RHEL, where perhaps /bin/sh is a symlink to /bin/bash while on Debian and Ubuntu it is a symlink to the more Posix compliant and faster /bin/dash)
Just use the mkdir(2) syscall and code
#include <cstdlib>
#include <cstdio>
#include <sys/stat.h>
#include <sys/types.h>
int main() {
for (int i=1; i<=4; i++) {
char buf[8];
snprintf(buf, sizeof(buf), "%d", i);
if (mkdir(buf, 0755))
{ perror("mkdir"); exit(EXIT_FAILURE); };
}
}
I hope you don't want to create a single directory named 1 2 3 4. It is possible and easy, but it really is poor taste. For your mental safety, use only letters, digits and underscores _ in directory names.
I am using snprintf(3) to convert an int to a character buffer. With C++11 you could use std::to_string and c_str ...
Read Advanced Linux Programming...
Using the mkdir(2) syscall instead of going thru a command invoked by system(3) has several important advantages:
it is much faster, you don't need to fork(2) a /bin/sh -c shell like system(3) should do.
it uses much less resources, since no additional process is fork-ed, so your program will still run when you have reached your limits (see setrlimit(2) ...)
it is more reliable. Should mkdir(2) fail you could (and should) handle the failure nicely. See errno(3) and strerror(3) ....