12#include <sys/socket.h>
15#include "arcane/IMesh.h"
16#include "arcane/IApplication.h"
17#include "arcane/IParallelMng.h"
18#include "arcane/IVariableMng.h"
19#include "arcane/IApplication.h"
20#include "arcane/FactoryService.h"
21#include "arcane/ServiceFinder2.h"
22#include "arcane/SharedVariable.h"
23#include "arcane/CommonVariables.h"
24#include "arcane/utils/ScopedPtr.h"
25#include "arcane/AbstractService.h"
26#include "arcane/utils/ApplicationInfo.h"
27#include "arcane/utils/ValueConvert.h"
29#include "arcane/utils/PlatformUtils.h"
30#include "arcane/utils/IOnlineDebuggerService.h"
31#include "arcane/ITransferValuesParallelOperation.h"
32#include "arcane/VariableCollection.h"
34#include "arcane/hyoda/HyodaArc.h"
35#include "arcane/hyoda/HyodaTcp.h"
36#define VARIABLE_PACKET_MAX_LENGTH 4*1024
52HyodaTcp(Hyoda *_hyoda,ISubDomain *sd,ITraceMng *tm,Integer adrs,
53 Integer port, Integer pyld,
bool break_at_startup)
63 ARCANE_UNUSED(break_at_startup);
64 if ((m_servaddr=(sockaddr_in *)malloc(
sizeof(
struct sockaddr_in)))==NULL)
65 ARCANE_FATAL(
"Could not allocate data space for sockaddr");
66 if ((m_fds=(pollfd *)malloc(
sizeof(
struct pollfd)))==NULL)
67 ARCANE_FATAL(
"Could not allocate data space for pollfd");
69 if (m_sub_domain->parallelMng()->commRank()!=0)
return;
71 if ((m_sockfd=socket(PF_INET, SOCK_STREAM, 0))<0)
72 fatal()<<
"[HyodaTcp::HyodaTcp] Error creating socket !";
73 memset(m_servaddr, 0,
sizeof(
struct sockaddr_in));
74 m_servaddr->sin_family=AF_INET;
75 m_servaddr->sin_port=htons(port);
77 m_servaddr->sin_addr.s_addr=adrs;
78 debug() <<
"[HyodaTcp::HyodaTcp] \33[7m @ " << m_servaddr->sin_addr.s_addr <<
" ?\33[m";
79 if (checkTcpError(connect(m_sockfd, (
struct sockaddr *) m_servaddr,
sizeof(
struct sockaddr_in)))!=0)
80 fatal()<<
"[HyodaTcp::HyodaTcp] Error connecting to socket!";
82 debug()<<
"[HyodaTcp::HyodaTcp] \33[7mConnected!\33[m";
83 memset(m_fds, 0,
sizeof(
struct pollfd));
90 getVariableCollectionAndSendItToHost();
103void HyodaTcp::disconect(
void){
104 debug()<<
"\33[7m[HyodaTcp::disconect]\33[m";
113void HyodaTcp::handshake(
void){
115 char pkt[VARIABLE_PACKET_MAX_LENGTH];
117 debug() <<
"[HyodaTcp::handshake]";
119 *(
unsigned int*)&pkt[0]=0xe73b2e9cul;
122 *(
unsigned int*)&pkt[of7]=platform::getProcessId();
123 debug() <<
"[HyodaTcp::handshake] pid=" << platform::getProcessId();
128 String hostname=platform::getHostName();
129 *(
unsigned int*)&pkt[of7]=hostname.len()+1;
130 if (sprintf(&pkt[of7+4],
"%s%c",hostname.localstr(),
'\0')!=(hostname.len()+1))
131 fatal()<<
"Error pushing hostname into packet !";
132 debug() <<
"[HyodaTcp::handshake] hostname=" << platform::getHostName();
133 of7+=4+hostname.len()+1;
136 String hyoda_bridge_broadcast_original_cmd=platform::getEnvironmentVariable(
"BRIDGE_BROADCAST_ORIGINAL_CMD");
137 if (hyoda_bridge_broadcast_original_cmd!=NULL){
138 debug() <<
"[HyodaTcp::handshake] Bridged from:"<<hyoda_bridge_broadcast_original_cmd;
139 *(
unsigned int*)&pkt[of7]=hyoda_bridge_broadcast_original_cmd.len()+1;
140 if (sprintf(&pkt[of7+4],
"%s%c",hyoda_bridge_broadcast_original_cmd.localstr(),
'\0')
141 !=(hyoda_bridge_broadcast_original_cmd.len()+1))
142 fatal()<<
"Error pushing hyoda_bridge_broadcast_original_cmd into packet !";
143 of7+=hyoda_bridge_broadcast_original_cmd.len()+1;
145 const ApplicationInfo& app_info = hyoda->application()->applicationInfo();
147 char** argv = *app_info.commandLineArgv();
149 *(
unsigned int*)&pkt[of7]=strlen(argv[0])+1;
150 if (sprintf(&pkt[of7+4],
"%s%c",argv[0],
'\0')!=(strlen(argv[0])+1))
151 fatal()<<
"Error pushing commandLineArgv into packet !";
152 debug() <<
"[HyodaTcp::handshake] command line:"<<argv[0];
153 of7+=strlen(argv[0])+1;
158 String slurm_job_id=platform::getEnvironmentVariable(
"SLURM_JOB_ID");
159 if (slurm_job_id!=NULL){
161 if (!builtInGetValue(sjobid,slurm_job_id)){
162 if (m_sub_domain->parallelMng()->commRank()==0) debug()<<
"\33[7m[Hyoda] slurm_job_id="<<sjobid<<
"\33[m";
163 debug() <<
"[HyodaTcp::handshake] SLURM_JOB_ID=" << sjobid;
164 *(
unsigned int*)&pkt[of7]=sjobid;
166 debug() <<
"[HyodaTcp::handshake] SLURM_JOB_ID but no builtInGetValue";
167 *(
unsigned int*)&pkt[of7]=0;
170 debug() <<
"[HyodaTcp::handshake] not Slurm'ed";
171 *(
unsigned int*)&pkt[of7]=0;
176 *(
unsigned int*)&pkt[4]=of7;
182 waitForAcknowledgment();
191getVariableCollectionAndSendItToHost(
void)
193 int varPacketOffset=4+4;
194 char varPacket[VARIABLE_PACKET_MAX_LENGTH];
195 VariableCollection variables = m_sub_domain->variableMng()->usedVariables();
197 *(
unsigned int*)&varPacket[0]=0xca6cd6f0ul;
198 debug()<<
"Variables count=" << variables.count();
199 for(VariableCollection::Enumerator ivar(variables); ++ivar; ){
200 IVariable* var = *ivar;
201 debug() <<
"[HyodaTcp::getVariableCollectionAndSendItToHost]"
202 <<
"Focusing variable"
203 <<
"name=" << var->name().localstr();
205 if (var->nbReference()==0) {debug() <<
"No nbReference";
continue;}
207 if (var->itemKind()!=IK_Node &&
208 var->itemKind()!=IK_Cell &&
209 var->itemKind()!=IK_Face &&
210 var->itemKind() != IK_Particle)
continue;
212 if (var->itemKind()!=IK_Particle && (!var->hasTag(
"PostProcessing")))
213 {debug() <<
"No PostProcessing";
continue;}
216 if (var->dataType()!=DT_Real)
continue;
217 debug() <<
"[HyodaTcp::getVariableCollectionAndSendItToHost] Found variable"
218 <<
" name=" <<var->name().localstr()
220 <<
", fullName=" <<var->fullName()
221 <<
", family=" <<var->itemFamilyName()
222 <<
", isUsed=" << var->isUsed()
223 <<
", nbReference=" << var->nbReference()
224 <<
", dimension=" << var->dimension()
225 <<
", isPartial=" <<var->isPartial()
226 <<
", var.hasTag(\"PostProcessing\")"<<var->hasTag(
"PostProcessing");
229 *(
unsigned int*)&varPacket[varPacketOffset]=var->name().len()+1;
231 debug() <<
"[HyodaTcp::getVariableCollectionAndSendItToHost] \33[7mVariable: "<<var->name()<<
"\33[m";
232 if (sprintf(&varPacket[varPacketOffset+4],
"%s%c",var->name().localstr(),
'\0')!=(var->name().len()+1))
233 fatal()<<
"Error pushing variable name into packet !";
234 ARCANE_ASSERT(varPacketOffset+4+var->name().len()+1<VARIABLE_PACKET_MAX_LENGTH, (
"VARIABLE_PACKET_MAX_LENGTH"));
235 varPacketOffset+=4+var->name().len()+1;
240 *(
unsigned int*)&varPacket[4]=varPacketOffset;
242 if (m_sub_domain->parallelMng()->commRank()==0)
243 send(varPacket,varPacketOffset);
244 waitForAcknowledgment();
254send(
const void *data,
size_t nleft)
256 size_t payload = m_payload;
258 debug() <<
"\33[7m[HyodaTcp::send] sending "<< nleft <<
" bytes of data, payload=" <<m_payload <<
"\33[m";
260 if (nleft<payload) payload=nleft;
261 if (wData(m_sockfd, (
unsigned char*)data+offset, payload)!=payload)
262 fatal()<<
"Error sending into socket !";
266 ARCANE_ASSERT(nleft==0, (
"[send] nleft!=0"));
267 debug() <<
"\33[7m[HyodaTcp::send] done\33[m";
276wData(
int sockd,
const void *vptr,
size_t n)
280 const char *buffer=(
char*)vptr;
282 if ((nwritten = write(sockd, buffer, nleft))<=0){
283 if (errno==EINTR) nwritten=0;
299void HyodaTcp::recvPov(
double *pov){
300 recvPacket((
char*)pov, 8*(1+3+1+1), -1);
301 debug() <<
"\33[7m[HyodaTcp::recvPov] ok\33[m";
305void HyodaTcp::recvPov(
double *pov,
int ms_timeout){
306 recvPacket((
char*)pov, 8*(1+3+1+1), ms_timeout);
307 debug() <<
"\33[7m[HyodaTcp::recv] pov "
308 <<
" scale=" << pov[0]
309 <<
" rot_x=" << pov[1]
310 <<
" rot_y=" << pov[2]
311 <<
" rot_z=" << pov[3]
317void HyodaTcp::sendAcknowledgmentPacket(
void){
320 *(
unsigned int*)&ack[0]=0x3e9ff203ul;
321 *(
unsigned int*)&ack[4]=0;
322 debug() <<
"\33[7m[HyodaTcp::sendAcknowledgmentPacket] ...\33[m";
324 debug() <<
"\33[7m[HyodaTcp::sendAcknowledgmentPacket] !\33[m";
327void HyodaTcp::waitForAcknowledgment(
void){
329 debug() <<
"\33[7m[HyodaTcp::waitForAcknowledgment] ?\33[m";
330 recvPacket((
char*)&ack[0], 4, -1);
331 debug() <<
"\33[7m[HyodaTcp::waitForAcknowledgment] !\33[m";
332 if ((*(
unsigned int*)&ack[0]) != 0x3e9ff203ul)
333 fatal() <<
"HyodaTcp::waitForAcknowledgment, ack[0]="<<*(
unsigned int*)&ack[0];
334 debug() <<
"\33[7m[HyodaTcp::waitForAcknowledgment] ok\33[m";
337void HyodaTcp::recvPacket(
char *pov,
int maxSize,
int ms_timeout){
339 debug() <<
"\33[7m[HyodaTcp::recvPacket] ...\33[m";
341 returned_events=poll(m_fds, m_nfds, ms_timeout);
342 }
while(returned_events==-1 && errno == EINTR);
343 if (returned_events==-1) fatal()<<
"Error polling socket !";
344 if (returned_events==0) debug()<<
"Timeout polling socket !";
345 if (!(m_fds->revents && POLLIN))
return;
346 rData(m_sockfd, (
char*)&pov[0], maxSize);
347 debug() <<
"\33[7m[HyodaTcp::recvPacket] !\33[m";
354ssize_t HyodaTcp::rData(
int sockd,
void *vptr,
size_t maxlen){
356 char c, *buffer=(
char*)vptr;
357 for(n=0; n<maxlen; n++){
358 if ((rc = read(sockd, &c, 1))==1){
388int HyodaTcp::checkTcpError(
int error){
389 if (error>=0)
return error;
392 debug() <<
"\33[7m" <<
"EACCES" <<
"\33[m:" <<
"Write permission is denied on the socket.";
395 debug() <<
"\33[7m" <<
"EPERM" <<
"\33[m:"
396 <<
"The user tried to connect to a broadcast address without having the socket broadcast flag enabled"
397 <<
"or the connection request failed because of a local firewall rule.";
400 debug() <<
"\33[7m" <<
"EADDRINUSE" <<
"\33[m:"
401 <<
"Local address is already in use.";
404 debug() <<
"\33[7m" <<
"EAFNOSUPPORT" <<
"\33[m:"
405 <<
"The passed address didn't have the correct address family in its sa_family field.";
408 debug() <<
"\33[7m" <<
"EADDRNOTAVAIL" <<
"\33[m:"
409 <<
"Non-existent interface was requested or the requested address was not local.";
412 debug() <<
"\33[7m" <<
"EALREADY" <<
"\33[m:"
413 <<
"The socket is non-blocking and a previous connection attempt has not yet been completed.";
416 debug() <<
"\33[7m" <<
"EBADF" <<
"\33[m:"
417 <<
" The file descriptor is not a valid index in the descriptor table.";
420 debug() <<
"\33[7m" <<
"ECONNREFUSED" <<
"\33[m:"
421 <<
"No one listening on the remote address.";
424 debug() <<
"\33[7m" <<
"EFAULT" <<
"\33[m:"
425 <<
"The socket structure address is outside the user's address space.";
428 debug() <<
"\33[7m" <<
"EINPROGRESS" <<
"\33[m:"
429 <<
"The socket is non-blocking and the connection cannot be completed immediately.";
432 debug() <<
"\33[7m" <<
"EINTR" <<
"\33[m:"
433 <<
"The system call was interrupted by a signal that was caught.";
436 debug() <<
"\33[7m" <<
"EISCONN" <<
"\33[m:"
437 <<
"The socket is already connected.";
440 debug() <<
"\33[7m" <<
"ENETUNREACH" <<
"\33[m:"
441 <<
"Network is unreachable.";
444 debug() <<
"\33[7m" <<
"ENOTSOCK" <<
"\33[m:"
445 <<
"The file descriptor is not associated with a socket.";
448 debug() <<
"\33[7m" <<
"ETIMEDOUT" <<
"\33[m:"
449 <<
"Timeout while attempting connection.";
451 default: debug()<<
"## UNKNOWN ERROR CODE error="<<error<<
", errno="<<errno;
Fichier de configuration d'Arcane.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Int32 Integer
Type représentant un entier.