Beruflich Dokumente
Kultur Dokumente
Yingwei Wang
Searching in Unix
Remove lines
Question: Write a filter mfilter.py that removes all lines except those whose first character other than whitespace is not % and whose last character other than whitespace (or
newline) is not ;.
Answer: My python code mfilter.py is:
import sys
data = open(sys.argv[1])
list = []
for line in data:
st = line.strip()
if st:
if st.startswith(%):
pass
Yingwei Wang
elif st.endswith(;):
pass
else:
list.append(line)
sys.stdout.writelines(list[:-1])
Just type % python mfilter.py mfilter_input.txt, then we can get the results we
want.
Break lines
Question: Write a Python script next2m.py, which from a file listing pairs of neighboring
atoms with any number of pairs per line, constructs a file listing the immediate neighbors
of each atom with the atom number printed first followed by a list of its neighbors. You
may find it convenient to use a dict of lists.
Answer: My python code break.py is:
import sys
maxlength = int(sys.argv[2])
data = open(sys.argv[1])
list = []
for line in data:
linelength = len(line)
# print linelength
if linelength ==1:
pass
else:
index = 0
while (index < linelength):
max = index + maxlength+1
if max < linelength:
temp = line.rfind( , index, max)
if temp > 0:
2
Yingwei Wang
sys.stdout.write(line[index:temp])
print \t
index = temp + 1
else:
temp = line.find( ,max)
if temp > 0:
sys.stdout.write(line[index:temp])
print \n
index = linelength + 1
else:
sys.stdout.write(line[index:-1])
print \n
index = linelength + 1
else:
sys.stdout.write(line[index:-1])
print \n
index = linelength + 1
Just type % python break.py break.dat 39, then we can get the results we want.
Find pairs
Question: Write a Python script next2m.py, which from a file listing pairs of neighboring
atoms with any number of pairs per line, constructs a file listing the immediate neighbors
of each atom with the atom number printed first followed by a list of its neighbors. You
may find it convenient to use a dict of lists.
Answer: My python code next2me.py is:
import sys
data = open(sys.argv[1])
dist = {}
for line in data:
ss = line.split()
sl = len(ss)
for k in range(0,sl,2):
3
Yingwei Wang
ford = ss[k]
back = ss[k+1]
if dist.has_key(ford):
list = []
pp = dist[ford]
list.extend(pp)
if pp.count(back) == 0:
list.append(back)
dist[ford] = list
else:
pass
else:
dist[ford] = [back]
if dist.has_key(back):
list = []
pp = dist[back]
list.extend(pp)
if pp.count(ford) == 0:
list.append(ford)
dist[back] = list
else:
pass
else:
dist[back] = [ford]
keylist = dist.keys()
keylist.sort()
for key in keylist:
skey = str(dist[key])
sys.stdout.write(key+\t+skey+\n)
If pairs.dat contains
1
3
9
13
17
19
3
5
10
15
18
22
1
5
9
14
19
17
6
11
13
17
2
5
9
15
19
1
7
12
16
20
3
5
13
15
19
4
8
9
17
21
Yingwei Wang
the result of
$ python next2me.py pairs.dat
is
1
10
11
12
13
14
15
16
17
18
19
2
20
21
22
3
4
5
6
7
8
9
[3, 17, 2]
[9]
[9]
[9]
[9, 15, 14]
[13]
[13, 16, 17]
[15]
[1, 15, 18, 19]
[17]
[17, 20, 21, 22]
[1]
[19]
[19]
[19]
[1, 4, 5]
[3]
[3, 6, 7, 8]
[5]
[5]
[5]
[10, 11, 12, 13]
Remark 4.1. My result is a little bit different from what we want. The reason is that the
type of all the items in my dist, which is a dictionary, including keys and values, is string,
instead of int.
CS501: Homework 2
Yingwei Wang
# equalizem.py
zt = 0.0
dz = []
dz.append(zt)
zz = []
zz.append(z[0])
zl = len(z)-1
for k in range(zl):
xt = z[k+1][0] - z[k][0]
Yingwei Wang
yt = z[k+1][1] - z[k][1]
zt = zt + math.sqrt(xt**2 + yt**2)
dz.append(zt)
dx.append(xt)
dy.append(yt)
h = dz[-1]/zl
rem = h
for j in range(zl):
xn = z[j][0]
yn = z[j][1]
R = dz[j+1] - dz[j]
r = rem - dz[j]
while (rem - dz[j+1] < 1e-6):
xx = dx[j]*r/R
yy = dy[j]*r/R
xn = xn + xx
yn = yn + yy
zz.append((xn,yn))
rem = rem + h
r = h
return zz
if __name__ == __main__:
print equalize([(0, 0), (3, 4), (6, 4), (6, 2), (6, 0)]); \
print [(0., 0.), (1.8, 2.4), (4., 4.), (6., 3.), (6., 0.)]
Find
Question: Write a Python script find.py which takes two arguments: (i) a valid path name
for some directory and (ii) a string. It examines the names of all files and subdirectories
that are below the given directory in the file hierarchy, and for each such file or subdirectory
whose name contains the given string, it prints the path of that file or subdirectory, one
path per line. If the given path is relative, it prints relative paths. If the given path is
absolute, it prints absolute paths.
2
Yingwei Wang
Yingwei Wang
junk/Myperl/pl2python
junk/Mypython/current/python2.5
Polynomial
Question:
Construct a module polynomial.py that defines a Polynomial class. The constructor
should take as its argument a dictionary whose keys are exponents of the variable x, each a
value that is an integer coefficient of the corresponding term. Terms with zero coefficients,
if any, should be omitted. Define a method for the str function that prints the polynomial
as illustrated in the template given below. Note that a leading plus sign is omitted and that
terms are ordered from highest exponent to lowest. Also, define a method that constructs
the product of two polynomials, one that evaluates a polynomial, and one that returns the
degree of a polynomial. Define the degree of the zero polynomial to be float(-inf).
Answer: My python code polynomial.py is:
#!/usr/bin/env python polynomial.py
class Polynomial(object):
def __init__(self, data):
try:
for key in data.keys():
if data[key] == 0:
del data[key]
except IndexError:
pass
self.data = data.copy()
def __repr__(self):
return Polynomial( + repr(self.data) + )
def __str__(self):
keylist = self.data.keys()
keylist.sort()
if len(keylist) == 0:
return 0
result = []
k = 0
4
Yingwei Wang
Yingwei Wang
res = 0
px = 1
for key in self.data:
px = x**key
res += px*self.data[key]
return res
def degree(self):
deg = 0
if self.data == {}:
deg = -float(inf)
else:
deg = max(self.data.keys())
return deg
if __name__ == __main__:
p = Polynomial({0:2, 2:-1})
print repr(p)
print p(%d) = %d % (3, p(3)); \
print p(3) = -7
print p*p; \
print 1x^4-4x^2+4x^0
q = Polynomial({2:1, 0:2})
print degree(%s) = %d % (str(q), q.degree()); \
print degree(1x^2+2x^0) = 2
print p, , q; \
print -1x^2+2x^0 1x^2+2x^0
print p*q; \
print -1x^4+4x^0
print Polynomial({}); \
print 0
print Polynomial({}).degree(); \
print -inf
rdata = {0:2, 2:-1}; r = Polynomial(rdata)
rdata[2] = 3
print r ;\
print -1x^2+2x^0
CS501: Homework 3
Yingwei Wang
Underflow
Question: Give an example of three double precision machine numbers x, y, z such that (x
* y) * z underflows to zero but x * (y * z) does not.
Answer:
x = 21000 , y = 21000 , z = 21000 .
Assemblem
Question: Complete the following template for script assemblem.py by completing the
definiiton of the vectorized function assembleV so that it has no (explicit) loop, i.e., it does
not use for, while, or recursion. A way of doing this is to use (i) relational ufuncs, (ii)
numpy.where, and (iii) tuples of arrays for indexing.
Answer:
#!/usr/bin/env python # assemblem.py
import numpy as np
import time
def assemble(N): # N = grid size
n = N*N # number of unknowns
a = np.zeros((n, n))
t0 = time.time()
for i in range(n):
ix = i // N; iy = i % N # (ix, iy) is the 2D grid index
Yingwei Wang
a[i, i] = 4.
if iy > 0:
a[i-1, i] = -1.
if iy < N-1: a[i+1, i] = -1.
if ix > 0:
a[i-N, i] = -1.
if ix < N-1: a[i+N, i] = -1.
t1 = time.time()
print elapsed time is, t1 - t0
return a
def assembleV(N):
n = N*N
a = np.zeros((n, n))
t0 = time.time()
b = 2*np.eye(N) - np.eye(N,M=None, k=1) - np.eye(N,M=None, k=-1)
c = np.eye(N)
a = np.kron(b,c) + np.kron(c,b)
t1 = time.time()
print elapsed time is, t1 - t0
return a
if __name__ == __main__:
N = 6
a = assemble(N)
aV = assembleV(N)
print np.all(aV == a)
Energy
Question: Complete the following template for a file coulomb.py by writing functions that
return the electrostatic energy (in kcal/mol) for a set of particles with 3-dimensional positions rvec[0], rvec[1], . . . , rvec[N-1] (in Angstroms) and partial charges q[0], q[1],
. . . , q[N-1] (in elementary charges). (Pardon the use of non-SI units!) The formula for N
particles is
N X
N
X
qi qj
electrostatic energy =
const
krj ri k2
i=1 j=i+1
where the constant is given in the code and the 2-norm is Euclidean distance.
1. The function energy should be a reasonably straightforward rendition of the formula
2
Yingwei Wang
Yingwei Wang
q2 = np.reshape(q1,(1,N**2))
qq = q2[rd]
rx = rvec[:,0]
rx1 = np.subtract.outer(rx,rx)
rx2 = np.reshape(rx1,(1,N**2))
rx3 = (rx2[rd])**2
ry = rvec[:,1]
ry1 = np.subtract.outer(ry,ry)
ry2 = np.reshape(ry1,(1,N**2))
ry3 = (ry2[rd])**2
rz = rvec[:,2]
rz1 = np.subtract.outer(rz,rz)
rz2 = np.reshape(rz1,(1,N**2))
rz3 = (rz2[rd])**2
rr = np.sqrt(rx3+ry3+rz3)
qr = qq/rr
eg = const*np.sum(qr)
return eg
if __name__ == __main__:
rvec = np.array([[0.8, 0., 1.], [0., -0.6, 1.]])
q = np.array([1.0, -1.0])
en = energy(q, rvec)
print energy = %.2f % en
#
env = energyV(q, rvec)
#
print energyV = %.2f % env
#
enw = energyW(q, rvec)
#
print energyW = %.2f % enw
execfile(readatoms.py)
import time
for energy_ in [energy, energyV, energyW]:
t0 = time.time()
en = energy_(q, rvec)
t1 = time.time()
print energy = %.2f, CPU time = %.2f % (en, t1 - t0)
Yingwei Wang
My timing:
1. energy : CPU time = 5.36
2. energyV : CPU time = 0.07
3. energyW : CPU time = 0.16
Actually, twice computation is done in energyW. That is why the time is doubled.
Power Spectrum
Question: Complete the following template for a file fourier.py by defining a function
powerspectrum that uses numpy.fft.fft to compute the power spectrum of data representing function values at equally spaced points on the interval 0 to 2. Its one parameter
is a numpy.ndarray with elements u[0], u[1], . . . , u[N-1] that are the values of some
function at points 0, h, . . . , (N 1)h where h = 2/N.
Answer:
#!/usr/bin/env python # fourier.py
import numpy as np
import pylab
def powerspectrum(u):
N = len(u)
M = int(N/2)
v = np.fft.fft(u)
p = abs(v/N)
pp = p[0:(M+1)]
#
print M
#
print len(pp)
pp[1:M] = 2*pp[1:M]
return pp
if __name__ == __main__:
N = 1024
n = int(N/2)
n1 = int(N/4)
pp = np.pi
h = 2*pp/N
5
Yingwei Wang
x = h*np.array(range(N))
u = np.ndarray((3,N),dtype = float)
xp = x/pp-1
u[0,] = 4*(np.abs(xp)-1)*xp
u[1,] = 8/pp*np.abs(xp) - 4/pp
u[2,0] = 0
u[2,n] = 0
u[2,1:n] = -8/(pp**2)
u[2,(n+1):N] = 8/(pp**2)
#
v0 = powerspectrum(u[0,])
v1 = powerspectrum(u[1,])
v2 = powerspectrum(u[2,])
m = range(1,n1,2)
p0, = pylab.semilogy(m,v0[m])
p1, = pylab.semilogy(m,v1[m])
p2, = pylab.semilogy(m,v2[m])
pylab.xlabel(Angular frequency (odd) m)
pylab.ylabel(Log power spectrum)
pylab.title(Fourier power spectrum)
pylab.legend([p0,p1,p2],[u_0,u_1,u_2])
pylab.savefig(Fourier)
pylab.show()
pylab.close
8 x
4
u1 (x) =
| 1|
2
8/ , if 0 < x < ,
8/ 2 ,
if < x < 2,
u2 (x) =
0,
otherwise.
u0 (x) = 4(|
Yingwei Wang
2. computes and plots the log power spectrum vs. angular frequency m for odd values of
m up to N/4 all on the same graph. See Fig.1.
101
u_0
u_1
u_2
100
10-1
10-2
10-3
10-4
10-5
10-6
10-7
10-8 0
50
100
150
200
Angular frequency (odd) m
250
300
CS501: Homework 4
Yingwei Wang
Stack
Question: The linked list implementation of a stack of the class notes is based on the
structures
typedef struct Node {
int value;
struct Node *next;
} Node;
typedef struct Stack {
Node *top;
} Stack;
Write a function Stack size that has as its argument a pointer to a stack and returns the
number of items in the stack: You are not allowed to augment the structures. The only way
to solve the problem is to chase pointers until a NULL pointer is reached and count Nodes
along the way.
Answer:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Node {
int value;
struct Node *next; // an incomplete type--at this point
Yingwei Wang
} Node;
typedef struct Stack {
Node *top;
} Stack;
Stack *Stack_new(void) {
Stack *stack = (Stack *)malloc(sizeof(Stack));
stack->top = NULL;
return stack;
}
void Stack_push(Stack *stack, int a) {
Node *newNode = (Node *)malloc(sizeof(Node));
if ( newNode == NULL ) {
fprintf(stderr, "Out of memory.\n");
exit(1);
}
newNode->value = a;
newNode->next = stack->top;
stack->top = newNode;
}
int Stack_pop(Stack *stack) {
Node *topNode = stack->top;
if ( topNode == NULL ) {
fprintf(stderr, "Cannot pop empty stack.\n");
exit(1);
}
int a = topNode->value;
stack->top = topNode->next;
free(topNode);
return a;
}
// begin to size
int Stack_size(Stack *stack) {
int size = 0;
Node *cNode = stack->top;
while (cNode != NULL){
cNode = cNode->next;
2
Yingwei Wang
size++;
}
return size;
}
Geometric hashing
Question: You will develop an efficient C code for computing short-range interactions for a
set of N particles in 1 dimension. (Extension to 3 dimensions would not be too difficult.)
Define constants = 120 0.00198721 kcal/mol, = 3.405
A, and rcut = 2.5. (120 K is the
temperature.) The energy for a particle pair separated by distance r is
4 ( )12 ( )6
r
r
if r < rcut and 0 otherwise. You are to write four functions, whose prototypes are given in
the main program below. Your code is to be contained in a single file energy.c.
1. (6 points) As a check, write a function energy, which does a straightforward calculation in order N 2 time by computing the distance (and nonzero energies) between
each pair of particles. The array r[] in the parameter list contains particle positions
in
Angstroms.
2. (6 points) Write a function calc grid that designs a grid of Nc cells, each of width
r cut. The number of cells Nc is to be calculated so that the grid just covers all
particles. (Having one cell too many is all right, but having one cell too few is not.)
Note that the floor function gives a quotient without the fractional part. The first
cell should begin at the least particle position rmin, which is also to be calculated.
3. (9 points) Write a function fill grid that places each particle into the appropriate
grid cell. This is done by creating a linked list of particle numbers for each cell. The
ordering of particles in the list is arbitrary. For simplicity, you will use arrays of ints
instead of pointers. The array element first[i] is to contain the first particle of
cell i, unless it is empty, in which case it is to contain -1. The particle that follows
particle m is to be placed in array element next[m]. Again, -1 is used if there is no
such particle. The addition of a particle to a list can be performed in the same manner
as the Stack push method in the class notes. For each particle, you need to compute
the index of its cell.
3
Yingwei Wang
4. (9 points) Write a function energyF that does a Fast order N calculation by employing
the grid cells to limit pair calculationsincluding distance calculationsto particles
that are either in the same cell or in adjacent cells.
Answer:
My energy.c is :
/* energy.c */
#include <stdio.h>
#include <math.h>
#include <time.h>
static double sigma = 3.405;
static double r_cut = 2.5*3.405;
static double ep = 120*0.00198721;
Yingwei Wang
return (en);
}
void calc_grid(int N, double r[N], double r_cut, double *rmin, int *Nc){
double p = r[0];
double q = r[0];
double m;
int i;
for (i = 1; i<N; i++)
{ if (r[i] < p)
p = r[i];
else if (r[i] > q)
q = r[i];
}
*rmin = p;
m = (q-p)/r_cut;
*Nc = floor(m)+1;
}
void fill_grid (int N, double r[N], double r_cut, double rmin, int Nc,
int first[Nc], int next[N])
{
int i;
int j = -2;
double dd;
int dn;
for (i=0; i<Nc; i++)
{ first[i] = -1;
}
for (i=0; i<N; i++)
{ next[i] = -1;
}
Yingwei Wang
{ dd = fabs(r[i] - rmin);
dn = floor(dd/r_cut);
if (first[dn] == -1)
first[dn] = i;
else
{ j = first[dn];
while(next[j] != -1)
{ j = next[j];
}
next[j] = i;
}
}
}
Yingwei Wang
{ mi = 1;
while (next[p] != -1)
{ mi++;
p = next[p];
}
}
fn[i] = mi;
// find the vector and energy
if (mi>1)
{double a[mi];
int j = 1;
p = first[i];
a[0] = r[p];
while (next[p] != -1)
{ p = next[p];
a[j] = r[p];
j++;
}
double ee=0;
ee = energy(mi, a);
en += ee;
}
}
// between two cells
for (i = 0; i<Nc-1; i++)
{
// find the sizes
int m1 = 0;
int m2 = 0;
m1 = fn[i];
m2 = fn[i+1];
if (m1 == 0 || m2 == 0)
{continue;}
else
{
// find the vectors
double a[m1];
7
Yingwei Wang
double b[m2];
int j1 = 1;
int j2 = 1;
p = first[i];
q = first[i+1];
a[0] = r[p];
b[0] = r[q];
while (next[p] != -1)
{ p = next[p];
a[j1] = r[p];
j1++;
}
while (next[q] != -1)
{ q = next[q];
b[j2] = r[q];
j2++;
}
// find the energies
double ee = 0;
ee = energy2(j1, a, j2, b);
en += ee;
}
}
return en;
}
Yingwei Wang
if (d < r_cut)
{ds = sigma/d;
en += 4*ep*(pow(ds,12) - pow(ds,6));
}
j++;
}
}
return (en);
}
function
function
function
function
energy is correct.
calc_grid is correct.
fill_grid is incorrect.
energyF is correct.
However, I want to say that actually my fill_grid is also correct. The only difference
between my output and the desired output is the order of the elements in the first and
next, which has no effect on the energy computation.
CS501: Homework 5
Yingwei Wang
Plotting
Question: The aim is to plot the time series for the total energy and as well particle positions
for the given script. There should be two plots. The second plot should show positions for all
40 particles. Use the data generated for all time steps. Do this by (i) removing statements
marked by //.., (ii) inserting disk file I/O operations into integrate.c, and (iii) appending
I/O and plotting commands to driver.py. Name the modified files integrate1.c and
driver1.py, respectively.
Answer: My integrate1.c and driver1.py are listed as following:
/* integrate1.c */
#include <stdio.h>
#include <stdlib.h>
#include <time.h> //..
static double mass = 39.95 * 1.66053886e-27 / 6.94771e-25;
// kcal/mol*ps^2/\AA^2
double forces(int N, double r[N], double F[N]);
int main(int argc, char *argv[argc]){
int nsteps = atoi(argv[1]);
double dt = atof(argv[2]); // ps
FILE *coordfile = fopen("coord.dat", "r");
FILE *rfile = fopen("rfile.dat","w");
FILE *vfile = fopen("vfile.dat","w");
FILE *efile = fopen("efile.dat","w");
Yingwei Wang
double F[N];
double pot_en = forces(N, r, F);
double kin_en = 0.;
for (int n = 1; n < N-1; n += 1) kin_en += v[n]*v[n];
kin_en *= 0.5*mass;
fprintf(efile,"%f\n", kin_en+pot_en);
for (int k = 1; k <= nsteps; k += 1){
for (int n = 1; n < N-1; n += 1){
v[n] += 0.5*dt*F[n]/mass;
r[n] += dt*v[n];
// fprintf(rfile,"%d ", k);
fprintf(rfile,"%f\n", r[n]);}
pot_en = forces(N, r, F);
for (int n = 1; n < N-1; n += 1) v[n] += 0.5*dt*F[n]/mass;
kin_en = 0.;
for (int n = 1; n < N-1; n += 1) {kin_en += v[n]*v[n];}
kin_en *= 0.5*mass;
fprintf(efile,"%f\n", kin_en + pot_en);
}
fclose(rfile);
fclose(vfile);
fclose(efile);
}
#!/usr/bin/env python
# driver1.py
2
Yingwei Wang
"""
Created on Wed Nov 07 23:29:07 2012
@author: Yingwei
"""
from subprocess import call
from init import initialize
from os import curdir, sep
import numpy as np
from pylab import *
N = 40
r = loadtxt(rfile.dat)
K = 500
r1 = r[0]*np.ones((K+1,1));
rn = r[N-1]*np.ones((K+1,1));
kk = range(K+1)
figure(1)
hold(True)
plot(kk,r1)
title(Particle position vs. time series)
plot(kk,rn)
for n in range(1,N-1,1):
rn = r[n];
rr = r.take([range(n+N-1,N+(K-1)*(N-2)+n,N-2)]);
rt = concatenate((rn,rr), axis=None);
plot(kk,rt);
3
Yingwei Wang
savefig(position.pdf)
show()
close()
en = loadtxt(efile.dat)
figure(2)
plot(kk,en)
title(Total energy vs. time series)
savefig(energy.pdf)
show()
close()
Yingwei Wang
160
140
120
100
80
60
40
20
0
0
100
200
300
400
500
Yingwei Wang
64.0
63.5
63.0
62.5
62.0
61.5
61.0
60.5
60.0
0
100
200
300
400
500
C to DL
Question: Create a dynamically loaded library for the function forces using the driver2_py.
Modify (the original) integrate.c so that it uses the library you created. Name the modified file integrate2.c.
Answer: My integrate2.c is
/* integrate2.c */
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <time.h> //..
#include <dlfcn.h> // dynamic linking functions
Yingwei Wang
//..
Yingwei Wang
}
Three line output:
energy = 1620.0801577672062
energy = 1620.0632661879254
CPU time = 0.00
Py to DL
Question: Supply integrate.py by writing a Python wrapper wrapDL.py module containing a wrapper forces for the C dynamically linked library function of the same name.
Answer: My wrapDL.py is
# wrapDL.py
"""
Created on Mon Nov 12 20:19:22 2012
@author: Yingwei
"""
import ctypes as C
import numpy as np
_Ffunc = np.ctypeslib.load_library(_Ffunc.so,.)
pt = C.POINTER(C.c_double)
_Ffunc.forces.argtypes = [C.c_int, pt, pt]
def forces(N,r,F):
en = _Ffunc.forces(N, r.ctypes.data_as(pt),F.ctypes.data_as(pt))
return en, F.ctypes.data_as(pt)
Three line output:
energy = 1620.0801577672062
energy = 1620.0632661879254
CPU time = 0.00
Disk
Question: You are to write a Python wrapper wrapDisk.py module containing a wrapper
forces that communicates with the C program using temporary disk files.
Answer: My wrapDisk.py is
8
Yingwei Wang
# wrapDisk.py
"""
Created on Mon Nov 12 20:19:22 2012
@author: Yingwei
"""
from tempfile import mktemp
from os import getcwd, remove
from subprocess import Popen
import numpy as np
def forces(r):
N = len(r)
iname = mktemp(dir = getcwd())
oname = mktemp(dir = getcwd())
ifile = open(iname,w)
ifile.write(np.getbuffer(r))
ifile.close()
proc = Popen(./Fprog + str(N) + + iname + + oname, shell=True)
proc.wait()
en = eval(proc.communicate()[0])
ofile = open(oname,r)
FF = ofile.readline().split()
F = np.frombuffer(FF)
ofile.close()
remove(iname); remove(oname)
return float(en), float(F)
Three line output:
energy = 646.16067378081834
energy = 646.14402599835068
CPU time = 0.00
Pipe
Question: Using disk files to communicate between separate processes is inefficient. More
direct communication can be accomplished using pipes or MPI (often implemented on top
of sockets) or yet other mechanisms. Answer: My wrapDisk.py is
9
Yingwei Wang
# wrapPipe.py
"""
Created on Mon Nov 12 20:19:22 2012
@author: Yingwei
"""
from tempfile import mktemp
from os import getcwd, remove,mkfifo
from subprocess import Popen
import numpy as np
def forces(r):
N = len(r)
iname = mktemp(dir = getcwd())
oname = mktemp(dir = getcwd())
mkfifo(iname)
mkfifo(oname)
proc = Popen(./Fprog + str(N) + + iname + + oname, shell=True)
ifile = open(iname,w)
ifile.write(np.getbuffer(r))
ifile.close()
en = eval(proc.communicate()[0])
ofile = open(oname,r)
proc.wait()
FF = ofile.readline().split()
F = np.frombuffer(FF)
ofile.close()
remove(iname); remove(oname)
return float(en), float(F)
Three line output:
energy = 646.16067378081834
energy = 646.14402599835068
CPU time = 0.00
10
CS501: Homework 6
Yingwei Wang
MPI
Yingwei Wang
Yingwei Wang
def forces(r):
N = len(r)
if rank == nproc-1:
N2 = N
else:
N2 = N + dN
r = np.concatenate((r, np.empty(dN)))
pot_en = 0.
F = np.zeros(N2)
for m in range(N2-1):
near = True
n = m + 1
while n < N2 and near:
rmn = r[n] - r[m]
if rmn < r_cut:
r_6 = (sigma/rmn)**6
pot_en += 4.*epsilon*r_6*(r_6 - 1.)
Fmn = 24.*epsilon*r_6*(2.*r_6 - 1.)/rmn
F[n] += Fmn; F[m] -= Fmn
else:
near = False
n += 1
return pot_en, F
main()
Yingwei Wang
energy = -1228.9434035336258
energy = -1228.943324123999
CPU time = 0.30
energy = -1228.9434035336258
energy = -1228.943324123999
CPU time = 0.16
Yingwei Wang
OpenMP
Yingwei Wang
Yingwei Wang