Skip to content

Commit 5d0402c

Browse files
committed
Initial impl of matrix passing from python
1 parent 0cc59ce commit 5d0402c

File tree

2 files changed

+103
-14
lines changed

2 files changed

+103
-14
lines changed

src/Dataflow/Engine/Controller/PythonImpl.cc

Lines changed: 87 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -424,11 +424,11 @@ namespace
424424
{
425425
throw std::invalid_argument("Module state key " + name + " not defined.");
426426
}
427-
state->setValue(apn, convert<AlgorithmParameter::Value>(object));
427+
state->setValue(apn, convert(object).value());
428428
}
429429
else
430430
{
431-
state->setTransientValue(apn, convert<boost::any>(object), false);
431+
state->setTransientValue(apn, convert(object), false);
432432
}
433433
}
434434
}
@@ -476,36 +476,114 @@ namespace
476476
boost::shared_ptr<PyPortsImpl> input_, output_;
477477

478478
//TODO: extract and use for state get/set
479-
template <class ReturnType>
480-
ReturnType convert(const boost::python::object& object) const
479+
Variable convert(const boost::python::object& object) const
481480
{
482481
/// @todo: yucky
483482
{
484483
boost::python::extract<int> e(object);
485484
if (e.check())
486485
{
487-
return e();
486+
return makeVariable("int", e());
488487
}
489488
}
490489
{
491490
boost::python::extract<double> e(object);
492491
if (e.check())
493492
{
494-
return e();
493+
return makeVariable("double", e());
495494
}
496495
}
497496
{
498497
boost::python::extract<std::string> e(object);
499498
if (e.check())
500499
{
501-
return e();
500+
return makeVariable("string", e());
502501
}
503502
}
504503
{
505504
boost::python::extract<bool> e(object);
506505
if (e.check())
507506
{
508-
return e();
507+
return makeVariable("bool", e());
508+
}
509+
}
510+
{
511+
boost::python::extract<boost::python::list> e(object);
512+
if (e.check())
513+
{
514+
std::cout << "hello i found a list, i am going to construct a matrix." << std::endl;
515+
auto list = e();
516+
auto length = len(list);
517+
bool makeDense;
518+
DenseMatrixHandle dense;
519+
if (length > 0)
520+
{
521+
boost::python::extract<boost::python::list> firstRow(list[0]);
522+
if (firstRow.check())
523+
{
524+
makeDense = true;
525+
dense.reset(new DenseMatrix(length, len(firstRow)));
526+
}
527+
else
528+
{
529+
boost::python::extract<std::string> innerString(list[0]);
530+
if (innerString.check())
531+
makeDense = false;
532+
else
533+
throw std::invalid_argument("Ill-formed list.");
534+
}
535+
}
536+
else
537+
{
538+
throw std::invalid_argument("Empty list.");
539+
}
540+
if (makeDense)
541+
{
542+
543+
for (int i = 0; i < length; ++i)
544+
{
545+
boost::python::extract<boost::python::list> rowList(list[i]);
546+
if (rowList.check())
547+
{
548+
auto row = rowList();
549+
if (len(row) != dense->ncols())
550+
throw std::invalid_argument("Attempted to convert into dense matrix but row lengths are not all equal.");
551+
for (int j = 0; j < len(row); ++j)
552+
{
553+
(*dense)(i,j) = boost::python::extract<double>(row[i]);
554+
}
555+
}
556+
}
557+
}
558+
else //sparse
559+
{
560+
std::cout << "TODO: sparse matrix conversion" << std::endl;
561+
}
562+
563+
//for (int i = 0; i < len(list); ++i)
564+
//{
565+
// boost::python::extract<boost::python::list> inner(list[i]);
566+
// if (inner.check())
567+
// {
568+
// std::cout << "hello i found a list of lists, i am going to construct a dense matrix" << std::endl;
569+
// }
570+
// else
571+
// {
572+
// boost::python::extract<std::string> innerString(list[i]);
573+
// if (innerString.check())
574+
// {
575+
// std::cout << "hello i found a list of lists, i am going to construct a sparse matrix" << std::endl;
576+
// }
577+
// else
578+
// {
579+
// std::cout << "hello i cannot figure out how to convert this list, so i am erroring" << std::endl;
580+
// throw std::invalid_argument("Ill-formed list.");
581+
// }
582+
// }
583+
//}
584+
585+
Variable x(Name("matrix"), dense, Variable::DATATYPE_VARIABLE);
586+
return x;
509587
}
510588
}
511589
//{
@@ -516,7 +594,7 @@ namespace
516594
// }
517595
//}
518596
std::cerr << "No known conversion from python object to C++ object" << std::endl;
519-
return ReturnType();
597+
return Variable();
520598
}
521599
};
522600
}

src/Modules/Python/PythonObjectForwarder.cc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include <Modules/Python/PythonObjectForwarder.h>
3030
#include <Core/Datatypes/String.h>
31+
#include <Core/Datatypes/DenseMatrix.h>
3132
#include <boost/thread.hpp>
3233

3334
using namespace SCIRun::Modules::Python;
@@ -78,10 +79,20 @@ void PythonObjectForwarder::execute()
7879

7980
if (valueOption)
8081
{
81-
auto valueStr = transient_value_cast<std::string>(valueOption);
82-
if (!valueStr.empty())
83-
sendOutput(PythonString, boost::make_shared<String>(valueStr));
84-
else
85-
sendOutput(PythonString, boost::make_shared<String>("Empty string or non-string received"));
82+
auto var = transient_value_cast<Variable>(valueOption);
83+
if (var.name().name() == "string")
84+
{
85+
auto valueStr = var.toString();
86+
if (!valueStr.empty())
87+
sendOutput(PythonString, boost::make_shared<String>(valueStr));
88+
else
89+
sendOutput(PythonString, boost::make_shared<String>("Empty string or non-string received"));
90+
}
91+
else if (var.name().name() == "matrix")
92+
{
93+
auto dense = boost::dynamic_pointer_cast<DenseMatrix>(var.getDatatype());
94+
if (dense)
95+
sendOutput(PythonMatrix, dense);
96+
}
8697
}
8798
}

0 commit comments

Comments
 (0)