well i am trying to do a program, where the process 0 should start the initialization of sending messages to a random process other than itself, then the random process selected should receive the message and send to another random process. This should happen until the requested number of messages to be sent is done, which is given by the user as input. I see that my program is either sending messages at the max 2 or else even none and giving me the following error
**ONE OF THE PROCESSES TERMINATED BADLY: CLEANING UP
APPLICATION TERMINATED WITH THE EXIT STRING: Terminated (signal 15)
**
Here is my code, lemme know whats the loop hole in it. The random generation part is not included, which is working fine
if(rank==0)
{
rnum=rgenerator(rank,size);
string++;
MPI_Send(&string, 50, MPI_INT, rnum, rnum, MPI_COMM_WORLD);
printf("\n process %d sends message to process %d",rank, rnum);
//MPI_Recv(&flag, 100, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
}
while(flag!=1)
{
if(MPI_Recv(&string, 50, MPI_INT, MPI_ANY_SOURCE, rank, MPI_COMM_WORLD, &status)==MPI_SUCCESS)
{
printf("\n process %d receives message from process %d count : %d",rank, status.MPI_SOURCE, string);
rnum=rgenerator(rank,size);
printf("\n Random num generated is %d",rnum);
string=string+1;
MPI_Send(&string, 50, MPI_INT, rnum, rnum, MPI_COMM_WORLD);
count++;
printf("\n process %d sends message to process %d", rank, rnum);
//MPI_Bcast(&count, 40, MPI_INT, rank, MPI_COMM_WORLD);
if(string==n)
{
printf("\n\n Messages reached");
flag=1;
}
}
else
flag=0;
}
You should make sure that you have the same number of send and recv operations. In your code you habe one send operation more than you have recv operations. Therefore one process will crash.
To avoid this you need to send only if your flag is not equal to 1:
//MPI_Send(&string, 50, MPI_INT, rnum, rnum, MPI_COMM_WORLD);
count++;
printf("\n process %d sends message to process %d", rank, rnum);
//MPI_Bcast(&count, 40, MPI_INT, rank, MPI_COMM_WORLD);
if(string==n)
{
printf("\n\n Messages reached");
flag=1;
}
if(flag!=1){//make sure that you need to send one message.
MPI_Send(&string, 50, MPI_INT, rnum, rnum, MPI_COMM_WORLD);
}
Related
I understand that calls to MPI_Irecv need to be paired with a MPI_Wait (or MPI_Test etc.; cf. here to complete. However, with the code below the MPI_Ssend seems to be forcing the Irecv to complete.
#include <iostream>
#include "mpi.h"
int main(int argc, char **argv) {
MPI_Init(&argc, &argv);
int rank = 0;
int size = 0;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size != 2)
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
int send_buffer_0 = 0;
int send_buffer_1 = 1;
int recv_buffer_0 = -1;
int recv_buffer_1 = -1;
MPI_Request request;
if (rank == 0) {
MPI_Irecv(&recv_buffer_0, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &request);
MPI_Ssend(&send_buffer_0, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else {
MPI_Irecv(&recv_buffer_1, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &request);
MPI_Ssend(&send_buffer_1, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
// MPI_Wait(&request, MPI_STATUS_IGNORE);
if (rank == 1)
std::cout << "Rank " << rank << " recv'd " << recv_buffer_1 << std::endl;
MPI_Finalize();
return 0;
}
If I change the sends to MPI_Send then the MPI_Wait is needed for the message to be received as I suspect the MPI implementation is buffering the send.
Is the MPI_Ssend call forcing the Irecv complete such that a wait or test is not needed? Is this implementation specific or expected from the standard?
Here is what the synchronous mode:
A send that uses the synchronous mode can be started whether or not a matching receive was posted. However, the send will complete successfully only if a matching receive is posted, and the receive operation has started to receive the message sent by the synchronous send. Thus, the completion of a synchronous send not only indicates that the send buffer can be reused, but it also indicates that the receiver has reached a certain point in its execution, namely that it has started executing the matching receive. If both sends and receives are blocking operations then the use of the synchronous mode provides synchronous communication semantics: a communication does not complete at either end before both processes rendezvous at the communication.
There is nothing here that would imply that you don't need to wait with the code you provided.
I have a microcontroller that sends stuff to an embedded Linux device over RS485 that shows up as a /dev/ttysomething. I use the QSerialPort class (from Qt 5.15.2) to read received data.
This basically works.
As a test, I send a block of 100 bytes, approximately once a second (in practice probably slightly slower than that). The value of the first byte of the first block is 0, then the value of each successive byte increases by 1. The receiving side expects that and checks whether something unexpected is received. It does this also once per second.
// In the header:
QTimer timer;
QSerialPort serialPort;
MyValues* myValues; // Contains some Q_PROPERTYs for displaying some values on the screen
// In the cpp:
void MyStuff::setup()
{
serialPort.setPortName("/dev/ttymxc2");
serialPort.setBaudRate(QSerialPort::Baud57600);
serialPort.setReadBufferSize(1);
if (!serialPort.open(QIODevice::ReadWrite))
{
qDebug() << "Cannot serialPort.open: " << serialPort.error();
return;
}
timer.setInterval(1000);
timer.setSingleShot(false);
QObject::connect(&timer, &QTimer::timeout, &timer, [=]()
{
// Display how many times the timer elapsed
myValues->setSendCount(myValues->sendCount() + 1);
{
auto info = qDebug().nospace();
info << "Available = " << serialPort.bytesAvailable() << ", ";
info << "Expected = ";
printHexByte(info, myValues->expectedValue());
}
QByteArray readData = serialPort.readAll();
if (serialPort.error() == QSerialPort::ReadError)
{
qDebug() << "serialPort.error is ReadError: " << serialPort.errorString();
}
else
{
auto line = qDebug().nospace();
line << "Read " << readData.length() << " bytes: ";
for (int i = 0; i < readData.length(); i++)
{
unsigned char actualValue = readData[i];
if (actualValue == myValues->expectedValue())
{
printHexByte(line, actualValue);
line << " ";
}
else
{
myValues->setMismatchCount(myValues->mismatchCount() + 1);
line << "\nMismatch: Expected = ";
printHexByte(line, myValues->expectedValue());
line << ", Actual = ";
printHexByte(line, actualValue);
line << "\n";
myValues->setExpectedValue(actualValue);
}
myValues->setExpectedValue(myValues->expectedValue() + 1);
}
}
});
timer.start();
}
What I would expect:
Assuming that the microcontroller sending the block and the reading happen sufficiently out-of-phase so that we don't read in the middle of a block.
Since the read buffer size is set to 1, I would expect that there is only ever one byte up for grabs, with the 99 other bytes of the block being discarded. So each time the timer elapses, one byte is available, serialPort.readAll() reads 1 byte and it's either the first or last byte of the block.
What actually happens:
Each time the timer elapses, one byte is available, serialPort.readAll() reads 1 byte, but its value is always the previous byte's value + 1, so no bytes are discarded.
So I was wondering: Where are the bytes buffered? And how do I prevent it?
Because if my program reading the data happens to go slower than the microcontroller sending it, I don't want everything to get out of sync and blow when the system eventually runs out of memory after running for hours, I'd rather detect dropped bytes through checksums and be notified of the problem immediately when it happens.
I'm pretty new to network programing. I've written a simple non-blocking TCP Server using winsock2 but it behaves in a weird way that I couldn't find any example of it in previously asked questions.
My server can only send a message with as many bytes as it previously received. For example, if previously it received a "rec_msg", when I try to send "message_to_send" it only sends "message".
I don't if it has any effect but the server is encapsulated with a pure static class. Here are the function via a recieve and send message:
int TCPServer_Test::receiveMessage(){
while(1)
{
memset(recvbuf, 0, DEFAULT_BUFLEN);
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
int err = WSAGetLastError();
int counter = 0;
if (iResult > 0)
{
std::cout << "Mesaj Alindi: " << recvbuf << std::endl;
break;
}
else if(err == WSAEWOULDBLOCK)
{
Sleep(200);
continue;
}
else if (iResult == 0){
printf("Connection closing...\n");
return -1;
}
else
{
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
assert(false);
}
}
}
void TCPServer_Test::sendMessage(char* Source){
strncpy(recvbuf, Source, DEFAULT_BUFLEN);
iSendResult = send( ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
assert(false);
}
else if (iSendResult == 0) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
assert(false);
}
else
{
printf("Bytes sent: %d\n", iSendResult);
}
memset(recvbuf, 0, sizeof(recvbuf));
}
I would appreciate any help directly related or not.
It looks like it happens because you are using iResult variable that contains amount of data received during previous recv call when sending data instead of supplying real size of the data to be sent like this:
size_t bytes_count_to_be_send = strlen(Source);
iSendResult = send( ClientSocket, Source, bytes_count_to_be_send, 0);
Also notice that there is no real need to copy data into buffer.
I am receiving segmentation fault on MPI_Test in the following code. The code involves a sender process and a receiver process. The sender process uses non-blocking send to send an integer value to the receiver process 1000000 times. This is just a test code. I am receiving a segmentation fault on MPI_Test in the sender process and am not able to figure out the reason why.
int main(int argc, char* argv[]){
MPI_Init(&argc,&argv);
int rank,nodes;
int i,j;
MPI_Status stat;
int size,wait;
int msgs = atoi(argv[1]);
MPI_Comm_size(MPI_COMM_WORLD, &nodes);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Request req[msgs][nodes-1],req1;
if(rank==0){
size=2;
for(i=0;i<msgs;i++){
for(j=1;j<nodes;j++){
MPI_Isend(&size,1,MPI_INT,
j,0,MPI_COMM_WORLD,&(req[i][j-1]));
}
}
wait = 1;
i=0,j=0;
while(wait){
printf("at i=%d j=%d\n",i,j);
MPI_Test(&req[i][j], &wait, &stat);
wait = 1-wait;
if(!wait){
j++;
if(j==nodes-1){
j=0;
i++;
wait=1;
}
else{
wait=1;
}
if(i==msgs){
wait=0;
}
}
}
printf("Finished\n");
}
else{
for(i=0;i<msgs;i++){
MPI_Irecv (&size,1,MPI_INT,0,0,MPI_COMM_WORLD,&req1);
wait = 1;
while(wait){
MPI_Test(&req1, &wait, &stat);
wait = 1-wait;
}
if(size!=2){
printf("Received size=%d rank=%d\n",size,rank);
}
size=0;
}
printf("Finished rank=%d\n",rank);
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}
The output of the above program is:-
Finished
OK
OK
OK
OK
OK
after which it gives the segmentation fault
mpirun noticed that process rank 0 with PID 4576 exited on signal 11 (Segmentation fault).
The idea is:
Connect arduino to PC via USB port (Windows 7, administrator logged
in)
System automatically execute command (for example: shutdown -s
-t 3600)
Is it possible to make that without using proxy application on host?
Here are two code snippets that address the fundamentals of this question. First, is a sketch that issues a "DIR" command. Obviously, this could be any command.
#include <stdio.h>
uint8_t command[] = "dir\0";
void setup()
{
Serial.begin(9600);
delay(10000);
Serial.write(command, 4);
}
void loop() {}
Second, is C code that reads COM5 and after receiving a string issues a command.
/*
* main.c
*
* Created on: Sep 29, 2013
* Author: Jack Coleman
*
* This software is for demonstration purposes only.
*
*/
#include <stdio.h>
#include <Windows.h>
//
// create a console that accepts data
// from a com port and issues it as system commands.
//
void display_config(COMMCONFIG *config_comm)
{
printf("BaudRate = ");
switch (config_comm->dcb.BaudRate)
{
case CBR_9600 : printf("9600\n");
}
printf("Parity = %d\n", config_comm->dcb.Parity);
printf("StopBits = %d\n", config_comm->dcb.StopBits);
printf("ByteSize = %d\n", config_comm->dcb.ByteSize);
fflush(stdout);
}
main() // Version 0
{
HANDLE hCOM5;
int config_size;
COMMCONFIG config_comm;
int retc;
int nr_read;
char *comm_char;
char sysline[271];
hCOM5 = CreateFile("COM5", GENERIC_READ, 0, 0,
OPEN_EXISTING, 0, NULL);
if (hCOM5 <= 0)
{
printf("unable to open COM5");
return;
}
GetCommConfig(hCOM5, &config_comm, &config_size);
config_comm.dcb.BaudRate = CBR_9600;
config_comm.dcb.Parity = NOPARITY;
config_comm.dcb.StopBits = ONESTOPBIT;
config_comm.dcb.ByteSize = 8;
retc = SetCommConfig(hCOM5, &config_comm, config_size);
if (retc == 0)
{
printf("SetCommConfig failed.\n");
return;
}
display_config(&config_comm);
// wait here for a possible, initial
// series of 0xFF.
comm_char = sysline;
do
{
ReadFile(hCOM5, comm_char, 1, &nr_read, NULL);
printf("%x nr_read = %d\n", *comm_char, nr_read);
fflush(stdout);
} while (nr_read == 0);
while (nr_read == 1)
{
if (*comm_char == 0x00)
{
printf("%s\n", &sysline[0]);
fflush(stdout);
system(&sysline[0]);
break;
} else {
comm_char++;
}
ReadFile(hCOM5, comm_char, 1, &nr_read, NULL);
printf("%02x\n", *comm_char);
fflush(stdout);
}
return;
}
This was a fun little coding problem. Several lessons were learned: 1) when communicating via a serial line, the C program will simply wait until the first byte is transmitted by the Arduino. There are no syncing chars to preface the data transmission (that is, if there are any they get stripped out by the system code); 2) It is possible to get zero (0) for the number of bytes read.
Could this be used to use an Arduino to issue a shut down command? Yes, but the program would have to be started (i.e. scheduled) and then it would wait for the Arduino to speak.