I've got a Makefile that's I'd like to parse the flags in /proc/cpuinfo and build up a list of available sse instruction sets to pass to gcc (-msse -msse2, etc). This is the best I've come up with so far, which Make isn't happy with at all:
DUMM = $(foreach tag,$(SSE_TAGS),
ifneq ($(shell cat /proc/cpuinfo | grep $(tag) | wc -l),"")
OPT_FLAG += -m$(tag)
endif)
So I thought I'd see here if anyone had any ideas.
For anyone that comes after me, this does what I want:
SSE_TAGS = $(shell /bin/grep -m 1 flags /proc/cpuinfo | /bin/grep -o \
'sse\|sse2\|sse3\|ssse3\|sse4a\|sse4.1\|sse4.2\|sse5')
NUM_PROC = $(shell cat /proc/cpuinfo | grep processor | wc -l)
ifneq (${SSE_TAGS},)
CCOPTS += -mfpmath=sse
CCOPTS += $(foreach tag,$(SSE_TAGS),-m$(tag))
endif
Related
I am currently doing parallel cascade simulations in GROMACS 4.6.5 and I am inputting the commands using a bash script:
#!/bin/bash
pdb2gmx -f step_04_01.pdb -o step_04_01.gro -water none -ff amber99sb -ignh
grompp -f minim.mdp -c step_04_01.gro -p topol.top -o em.tpr
mdrun -v -deffnm em
grompp -f nvt.mdp -c em.gro -p topol.top -o nvt.tpr
mdrun -v -deffnm nvt
grompp -f md.mdp -c nvt.gro -t nvt.cpt -p topol.top -o step_04_01.tpr
mdrun -v -deffnm step_04_01
trjconv -s step_04_01.tpr -f step_04_01.xtc -pbc mol -o step_04_01_pbc.xtc
g_rms -s itasser_2znh.tpr -f step_04_01_pbc.xtc -o step_04_01_rmsd.xvg
Commands such as trjconv and g_rms require user interaction to select options. For instance when running trjconv you are given:
Select group for output
Group 0 ( System) has 6241 elements
Group 1 ( Protein) has 6241 elements
Group 2 ( Protein-H) has 3126 elements
Group 3 ( C-alpha) has 394 elements
Group 4 ( Backbone) has 1182 elements
Group 5 ( MainChain) has 1577 elements
Group 6 ( MainChain+Cb) has 1949 elements
Group 7 ( MainChain+H) has 1956 elements
Group 8 ( SideChain) has 4285 elements
Group 9 ( SideChain-H) has 1549 elements
Select a group:
And the user is expected to enter eg. 0 into the terminal to select Group 0. I have tried using expect and send, eg:
trjconv -s step_04_01.tpr -f step_04_01.xtc -pbc mol -o step_04_01_pbc.xtc
expect "Select group: "
send "0"
However this does not work. I have also tried using -flag like in http://www.gromacs.org/Documentation/How-tos/Using_Commands_in_Scripts#Within_Script but it says that it is not a recognised input.
Is my expect \ send formatted correctly? Is there another way around this in GROMACS?
I don't know gromacs but I think they are just asking you to to use the bash syntax:
yourcomand ... <<EOF
1st answer to a question
2nd answer to a question
EOF
so you might have
trjconv -s step_04_01.tpr -f step_04_01.xtc -pbc mol -o step_04_01_pbc.xtc <<EOF
0
EOF
You can use
echo 0 | trjconv -s step_04_01.tpr -f step_04_01.xtc -pbc mol -o step_04_01_pbc.xtc
And if you need to have multiple inputs, just use
echo 4 4 | g_rms -s itasser_2znh.tpr -f step_04_01_pbc.xtc -o step_04_01_rmsd.xvg
Output only specific var from text. In that case:
echo "ote -C -pname ap01 -HLS 134 -db 1 -instance 43 -log ap01"
Want to get only this value from "-pname"
Exptected result:
ap01
-log takes a string. That string could be -pname. The existing solutions so far fail to handle that and treat the value of the -log parameter as the start of another argument.
You'll have to recreate the argument parsing ote performs if you want a robust solution. The following is well on your way to do that.
echo ... | perl -MGetopt::Long -nle'
local #ARGV = split;
GetOptions(\%args, "C", "pname=s", "HLS=i", "db=i", "instant=i", "log=s")
&& defined($args{pname})
&& print($args{pname});
'
This will deal with a doubled -pname.
echo "ote -C -pname ap01 -HLS 134 -db 1 -instance 43 -log ap01" |\
perl -ne 'print ( /\s+-pname\s+([^-]\S*)/ )'
As ikegami notes below, if you should happen to want to use dashes as the first character of this value, the only way I know that you can be sure you're getting a value and not another switch is more complicated. One way is to do a negative lookahead for all known switches:
echo "ote -C -pname -pname -ap01- -HLS 134 -db 1 -instance 43 -log ap01" |\
perl -ne 'print ( /\s+-pname\s+(?!-(?:pname|other|known|switches))(\S+)/ )'
echo "ote -C -pname ap01 -HLS 134 -db 1 -instance 43 -log ap01" | \
awk '{for (i = 1; i <= NF; i++) {if ($i == "-pname") { print $(i+1); break; } } }'
echo "ote -C -pname ap01 -HLS 134 -db 1 -instance 43 -log ap01" | \
perl -pe '($_)= /-pname\s+([^-]\S*)/'
grep with look behind?
$ grep -Po '(?<=-pname )[^ ]*' <<< "ote -C -pname ap01 -HLS 134 -db 1 -instance 43 -log ap01"
ap01
As there might be many -pname in the string (see comments below), you can then "play" with head and tail to get the value you want.
Explanation
This uses -P for Perl Regex and -o for "print only the matched parts of a machine line".
(?<=-pname ) is a look-behind: match strings that are preceeded by -pname (note the space).
[^ ]* match any set of characters until a space is found.
You can simply use (GNU) grep:
$ echo "ote -C -pname ap01 -HLS 134 -pname foo -db 1 -instance 43 -log ap01" |
grep -Po -- '-pname \K[^ ]+'
ap01
Explanation
The -P enables Perl Compatible Regular Expressions (PCREs) which gives us \K (meaning "discard anything matched up to this point). The -o means "print only the matched portion of the line. So, we then look for the string -pname followed by a space and then as many consecutive non-space characters as possible ([^ ]+). Because of the \K, everything before that is discarded and because of the -o, only the matched portion is printed.
This will work for an arbitrary number of -pname flags as long as none of their values contain spaces.
This looks simple
xargs -n1 | sed -n "/-pname/,//p" | tail -n1
I have the script which (as intended) allows me to see the difference in the opcodes generated for the different architectures (especially intrested in x87 instructions on x86 vs x86_64).
#!/usr/bin/env bash
cat - <<__EOF> a.cpp
int main()
{
double const x(1.0);
asm volatile ("fldl (%0)" : : "a" (&x));
return 0;
}
__EOF
EXEC_STR='g++ a.cpp -c -O0 -o /dev/null -m${BITNESS} -mfpmath=387 -Wa,-adhlns="${BITNESS}.lst"'
FILTER_STR='awk "/\/APP/, /\/NO_APP/" ${BITNESS}.lst | cut -f 2- > ${BITNESS}_.lst'
BITNESS=32 bash -c "${EXEC_STR} && ${FILTER_STR}"
BITNESS=64 bash -c "${EXEC_STR} && ${FILTER_STR}"
diff -w -B 32_.lst 64_.lst
Output:
3c3
< fldl (%eax)
---
> fldl (%rax)
But cut -f 2- cut out the column with opcode too (this is udesirable), in addition to cutting out the first column.
Are there other ways to get the desired result? And how to filter out the text?
I have a bash script checking the number of CPUs on the platform to efficiently use -j option for make, repo, etc. I use this:
JOBS=$(cat /proc/cpuinfo | grep processor | tail -1 | sed "s,^.*:.*\([0-9].*\)$,\1,")
echo -e "4\n$JOBS" | sort -r | tail -1
It works fine. But, I am wondering if there was any built-in function which does the same thing (i.e. calculating the minimum, or maximum)?
If you mean to get MAX(4,$JOBS), use this:
echo $((JOBS>4 ? JOBS : 4))
Had a similar situation where I had to find the minimum out of several variables, and a somewhat different solution I found useful was sort
#!/bin/bash
min_number() {
printf "%s\n" "$#" | sort -g | head -n1
}
v1=3
v2=2
v3=5
v4=1
min="$(min_number $v1 $v2 $v3 $v4)"
I guess It's not the most efficient trick, but for a small constant number of variables, it shouldn't matter much - and it's more readable than nesting ternary operators.
EDIT: Referring Nick's great comment - this method can be expanded to any type of sort usage:
#!/bin/bash
min() {
printf "%s\n" "${#:2}" | sort "$1" | head -n1
}
max() {
# using sort's -r (reverse) option - using tail instead of head is also possible
min ${1}r ${#:2}
}
min -g 3 2 5 1
max -g 1.5 5.2 2.5 1.2 5.7
min -h 25M 13G 99K 1098M
max -d "Lorem" "ipsum" "dolor" "sit" "amet"
min -M "OCT" "APR" "SEP" "FEB" "JUL"
How do i unstrip a stripped object file ?
Does eu-unstrip from elfutils can make this for me ?
I need this to convert a zImage kernel to vmlinux without recompiling.
This is apart of my script:
magic="1f 8b 08 00"
full_line=$(od -A d -t x1 zImage | grep "$magic" )
offset_full_line=$( echo $full_line | cut -f1 -d" ")
data_full_line=$( echo $full_line | cut -f1 -d" " --complement )
index=$[ $( awk -v a="$data_full_line" -v b="$magic" 'BEGIN{print index(a,b)}' ) / 3 ]
offset=$[ 10#$offset_full_line + $index ]
dd if=zImage bs=1 skip=$offset 2>/dev/null | zcat > vmlinux
But my result vmlinux has an unknown format because it doesn't contain ELF headers, so how can i recover those headers ?
Your question makes no sense. If the object file has been stripped, then obviously the information is no longer there. You've got nowhere to extract the stripped data from.