11#include "arcane/IApplication.h"
12#include "arcane/IParallelMng.h"
14#include "arcane/AbstractService.h"
15#include "arcane/FactoryService.h"
17#include "arcane/IVariableMng.h"
18#include "arcane/SharedVariable.h"
19#include "arcane/CommonVariables.h"
21#include "arcane/IMesh.h"
22#include "arcane/IItemFamily.h"
24#include <arcane/MathUtils.h>
25#include <arcane/Timer.h>
26#include <arcane/IParallelMng.h>
27#include <arcane/ITimeLoopMng.h>
30#include <arcane/mathlink/mathlink.h>
40mathlink::mathlink(
const ServiceBuildInfo & sbi):
42 m_sub_domain(sbi.subDomain()),
45 mathtmr(new Timer(m_sub_domain,
"mathlink",Timer::TimerReal)){}
51mathlink::~mathlink(){}
61 if (m_sub_domain->parallelMng()->commRank()!=0)
return;
64 debug()<<
"[mathlink::link]"<<
" linking?"
65 <<
" (commSize=" << m_sub_domain->parallelMng()->commSize()
66 <<
", commRank=" << m_sub_domain->parallelMng()->commRank()<<
")";
69 mathenv = MLInitialize((
char *)NULL);
70 if(mathenv == (MLENV)NULL)
72 debug()<<
"[mathlink::link] initialized!";
79 char master_string[]=
"-linkname /cea/produits1/mathematica-8.0.0/Executables/math -mathlink -linkmode launch -linkprotocol SharedMemory";
80 char slave_string[] =
"-linkname /cea/produits1/mathematica-8.0.0/Executables/math -mathlink -linkmode connect -linkprotocol tcpip";
81 if (m_sub_domain->parallelMng()->commRank()==0){
82 mathlnk = MLOpenString(mathenv, master_string, &error);
84 mathlnk = MLOpenString(mathenv, slave_string, &error);
86 if ((mathlnk==(MLINK)NULL)||(error!=MLEOK))
91 if (!MLActivate(mathlnk))
93 info()<<
"Mathematica launched on rank #"<<m_sub_domain->parallelMng()->commRank();
101void mathlink::unlink(){
102 info()<<__FUNCTION__<<
" MLClose";
103 if (!mathlnk)
return;
104 MLPutFunction(mathlnk,
"Exit", 0);
107 info()<<__FUNCTION__<<
" MLDeinitialize";
108 if (!mathenv)
return;
110 MLDeinitialize(mathenv);
116static int read_and_print_expression( MLINK lp);
117static int read_and_print_atom( MLINK lp,
int tag){
119 if( tag == MLTKSTR) putchar(
'"');
120 if( MLGetString( lp, &s)){
125 if( tag == MLTKSTR) putchar(
'"');
127 return MLError( lp) == MLEOK;
129static int read_and_print_function( MLINK lp){
132 if( ! MLGetArgCount( lp, &len))
return 0;
134 printf(
"\n%*.*s", indent, indent,
"");
135 if( read_and_print_expression( lp) == 0)
return 0;
137 for( i = 1; i <=
len; ++i) {
138 if( read_and_print_expression( lp) == 0)
return 0;
139 if( i < len) printf(
", ");
145static int read_and_print_expression( MLINK lp){
147 switch (tag = MLGetNext( lp)) {
152 return read_and_print_atom(lp, tag);
154 return read_and_print_function(lp);
156 printf(
"MLTKERROR!\n");
159 default: printf(
"\nread_and_print_expression default!");
168void mathlink::skipAnyPacketsBeforeTheFirstReturnPacket(){
170 while( (pkt = MLNextPacket(mathlnk), pkt) && pkt != RETURNPKT) {
171 MLNewPacket(mathlnk);
172 if (MLError(mathlnk)) mathlink::error();
181Integer mathlink::Prime(Integer n){
184 debug()<<
"[mathlink::Prime] n=" << n;
185 MLPutFunction(mathlnk,
"EvaluatePacket", 1L);
186 MLPutFunction(mathlnk,
"Prime", 1L);
187 MLPutInteger64(mathlnk, n);
188 MLEndPacket(mathlnk);
189 skipAnyPacketsBeforeTheFirstReturnPacket();
190 if (MLGetNext(mathlnk)!=MLTKINT) mathlink::error();
191 MLGetInteger64(mathlnk, &prime);
192 debug()<<
"[mathlink::Prime] returning " << prime;
200void mathlink::tests(){
201 testFactorInteger(7420738134810L);
202 UniqueArray<Integer> coefs;
206 testLinearProgramming(coefs.view());
213void mathlink::testFactorInteger(Int64 n){
214 info()<<__FUNCTION__<<
" is now factoring "<<n;
219 Timer::Sentry ts(mathtmr);
221 MLPutFunction(mathlnk,
"EvaluatePacket", 1L);
222 MLPutFunction(mathlnk,
"FactorInteger", 1L);
223 MLPutInteger64(mathlnk, n);
224 MLEndPacket(mathlnk);
225 while( (pkt = MLNextPacket(mathlnk), pkt) && pkt != RETURNPKT) {
226 MLNewPacket(mathlnk);
227 if (MLError(mathlnk)) mathlink::error();
229 if (!MLCheckFunction(mathlnk,
"List", &len)) mathlink::error();
230 for (k = 1; k <=
len; k++) {
231 if (MLCheckFunction(mathlnk,
"List", &lenp)
233 && MLGetInteger64(mathlnk, &prime)
234 && MLGetInteger(mathlnk, &expt)
236 info()<<prime<<
"^"<< expt;
237 }
else mathlink::error();
240 info()<<__FUNCTION__<<
" "<<mathtmr->lastActivationTime()<<
"s";
248void mathlink::testLinearProgramming(ArrayView<Integer> coefs){
252 Timer::Sentry ts(mathtmr);
253 MLPutFunction(mathlnk,
"EvaluatePacket", 1);
254 MLPutFunction(mathlnk,
"LinearProgramming", 5);
255 int c[]={1,1,1,1,1,1};
256 int m[5][6]={{7, 4, 3, 0, 0, 0},
261 int b[5][2]={{9, -1}, {9, -1}, {1, 0}, {1, 0}, {1, 0}};
262 int l[6][2]={{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}};
263 MLPutIntegerList(mathlnk, c, 6);
264 MLPutFunction(mathlnk,
"List", 5);
265 MLPutIntegerList(mathlnk, m[0], 6);
266 MLPutIntegerList(mathlnk, m[1], 6);
267 MLPutIntegerList(mathlnk, m[2], 6);
268 MLPutIntegerList(mathlnk, m[3], 6);
269 MLPutIntegerList(mathlnk, m[4], 6);
270 MLPutFunction(mathlnk,
"List", 5);
271 MLPutIntegerList(mathlnk, b[0], 2);
272 MLPutIntegerList(mathlnk, b[1], 2);
273 MLPutIntegerList(mathlnk, b[2], 2);
274 MLPutIntegerList(mathlnk, b[3], 2);
275 MLPutIntegerList(mathlnk, b[4], 2);
276 MLPutFunction(mathlnk,
"List", 6);
277 MLPutIntegerList(mathlnk, l[0], 2);
278 MLPutIntegerList(mathlnk, l[1], 2);
279 MLPutIntegerList(mathlnk, l[2], 2);
280 MLPutIntegerList(mathlnk, l[3], 2);
281 MLPutIntegerList(mathlnk, l[4], 2);
282 MLPutIntegerList(mathlnk, l[5], 2);
283 MLPutFunction(mathlnk,
"List", 6);
284 MLPutSymbol(mathlnk,
"Integers");
285 MLPutSymbol(mathlnk,
"Integers");
286 MLPutSymbol(mathlnk,
"Integers");
287 MLPutSymbol(mathlnk,
"Integers");
288 MLPutSymbol(mathlnk,
"Integers");
289 MLPutSymbol(mathlnk,
"Integers");
290 MLEndPacket(mathlnk);
291 while( (pkt = MLNextPacket(mathlnk), pkt) && pkt != RETURNPKT) {
292 MLNewPacket(mathlnk);
293 if (MLError(mathlnk)) mathlink::error();
295 if (!MLCheckFunction(mathlnk,
"List", &len)) mathlink::error();
296 for (k = 1; k <=
len; k++) {
297 if (MLGetInteger(mathlnk, &sol)){
299 }
else mathlink::error();
302 info()<<__FUNCTION__<<
" "<<mathtmr->lastActivationTime()<<
"s";
309void mathlink::error(){
310 if (MLError(mathlnk))
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Exception lorsqu'une erreur fatale est survenue.
Integer len(const char *s)
Retourne la longueur de la chaîne s.
Int32 Integer
Type représentant un entier.