[please disregard my prev message - the misprint in the subject line is
now fixed]
---
Dear GUILE Developers
I would like to embed guile interpreter into my application - a
parallel program using MPI (message passing interface) and operating
massive data and computations. I would like that program to be able to
process standard input in order to be able to have a live interactive
session with my application. Below I describe the problem i
encountered.
I am currently using Tcl as an embedded
interpreter but looking for a possibility of other alternatives.
Since Tcl does not take over the control of stdin, I am currently just
reading stdin on the MPI process zero until the Tcl command is complete
(checking with Tcl_CommandComplete after each line of stdin) and when
the command is complete i stop reading stdin, copy the string to all
the other MPI processes using MPI_Bcast and process (with Tcl_Eval)
them on worker processes.
With guile however, I am limited to using
scm_shell(argc, argv);
which is supposed to do the stdin processing itself, - I hoped it would
even in the parallel environment. I inserted
MPI_Init(&argc,&argv);
MPI_Finalize()
into the tortoise.c program of the guile tutorial (the complete copy of
the program is attached) and compiled it with 'mpicc', but I do not get
the expected behavior, for example when i run on 4 processes:
mpirun -np 4 ./tortoise2
guile> (tortoise-move 100)
the next guile prompt does not appear after the entered command has
completed.
I looked into the guile archieves using search "MPI" and found
that another person was having the same problem one year ago.
That user has recieved a very informative message :
http://lists.gnu.org/archive/html/guile-user/2005-02/msg00018.html
but unfortunately, the thread stops there.
I did some followup and found nice documentation on setting custom
ports on stdin at
http://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Port-Types.html#Port-Types
but the resources of my expertise in scheme and setting custom
ports have exhausted there.
There are many people using MPI, I think a solution very be greatly
appreciated by a sizable community of MPI users.
Thank you.
Regards,
Alexander Shirokov
--
/* Be-Guiled version of the program */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#define WINDOW_SIZE 500
#include <guile/gh.h>
#include <mpi.h>
int myid, serv, nproc;
Display *theDisplay;
Window theWindow;
Screen *theScreen;
GC theGC;
double currentX;
double currentY;
double currentDirection;
int penDown;
#include <math.h>
#define DEGREES_TO_RADIANS (3.1415926535897932384626433832795029L/180.0)
SCM tortoise_reset()
{
currentX = currentY = WINDOW_SIZE/2;
currentDirection = 0;
penDown = 1;
return SCM_EOL;
}
SCM tortoise_pendown()
{
penDown = 1;
return SCM_EOL;
}
SCM tortoise_penup()
{
penDown = 0;
return SCM_EOL;
}
SCM tortoise_turn(SCM s_degrees)
{
int degrees = SCM_INUM(s_degrees);
currentDirection += (double)degrees;
return SCM_EOL;
}
SCM tortoise_move(SCM s_steps)
{
double newX, newY;
int steps = SCM_INUM(s_steps);
/* first work out the new endpoint */
newX = currentX + sin(currentDirection*DEGREES_TO_RADIANS)*(double)steps;
newY = currentY - cos(currentDirection*DEGREES_TO_RADIANS)*(double)steps;
/* if the pen is down, draw a line */
if (penDown) XDrawLine(theDisplay, theWindow, theGC,
(int)currentX, (int)currentY, (int)newX, (int)newY);
/* in either case, move the tortoise */
currentX = newX;
currentY = newY;
return SCM_EOL;
}
void register_procs(void)
{
gh_new_procedure("tortoise-reset", tortoise_reset, 0, 0, 0);
gh_new_procedure("tortoise-pendown", tortoise_pendown, 0, 0, 0);
gh_new_procedure("tortoise-penup", tortoise_penup, 0, 0, 0);
gh_new_procedure("tortoise-turn", tortoise_turn, 1, 0, 0);
gh_new_procedure("tortoise-move", tortoise_move, 1, 0, 0);
}
void inner_main(int argc, char **argv)
{
register_procs();
scm_shell(argc, argv);
MPI_Finalize();
}
int main(int argc, char *argv[])
{
char pname[256];
char fname[256];
int reslen;
MPI_Comm world;
serv = 0;
world = MPI_COMM_WORLD;
MPI_Init(&argc,&argv);
MPI_Comm_rank (world, &myid);
MPI_Comm_size (world, &nproc);
if(myid != 0){
char *name;
asprintf(&name, "so-%d", myid);
stdout = freopen(name, "w", stdout);
if(!stdout){
printf("Error: can not reopen stdout (%s:%d)\n", __FILE__, __LINE__);
exit(2);
}
free(name);
}
theDisplay = XOpenDisplay(NULL);
XSynchronize(theDisplay, True);
theScreen = DefaultScreenOfDisplay(theDisplay);
theWindow = XCreateSimpleWindow(theDisplay, RootWindowOfScreen(theScreen),
0, 0,
WINDOW_SIZE, WINDOW_SIZE, 0,
BlackPixelOfScreen(theScreen),
WhitePixelOfScreen(theScreen));
theGC = XCreateGC(theDisplay, theWindow, 0L, NULL);
XSetForeground(theDisplay, theGC, BlackPixelOfScreen(theScreen));
XMapWindow(theDisplay,theWindow);
/* more stuff to come here . . */
tortoise_reset();
gh_enter(argc, argv, inner_main);
return(0); /* never reached */
return 0;
}
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user