PLearn 0.1
MemoryStressTest.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // MemoryStressTest.cc
00004 //
00005 // Copyright (C) 2005 Nicolas Chapados 
00006 // Copyright (C) 2005 Olivier Delalleau 
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are met:
00010 // 
00011 //  1. Redistributions of source code must retain the above copyright
00012 //     notice, this list of conditions and the following disclaimer.
00013 // 
00014 //  2. Redistributions in binary form must reproduce the above copyright
00015 //     notice, this list of conditions and the following disclaimer in the
00016 //     documentation and/or other materials provided with the distribution.
00017 // 
00018 //  3. The name of the authors may not be used to endorse or promote
00019 //     products derived from this software without specific prior written
00020 //     permission.
00021 // 
00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 // 
00033 // This file is part of the PLearn library. For more information on the PLearn
00034 // library, go to the PLearn Web site at www.plearn.org
00035 
00036 /* *******************************************************      
00037    * $Id: .pyskeleton_header 544 2003-09-01 00:05:31Z plearner $ 
00038    ******************************************************* */
00039 
00040 // Authors: Nicolas Chapados, Olivier Delalleau
00041 
00045 #include <plearn/python/PythonCodeSnippet.h>
00046 #include <iostream>
00047 #include <vector>
00048 #include <map>
00049 
00050 #include "MemoryStressTest.h"
00051 #include <plearn/io/openString.h>
00052 #include <plearn/base/ProgressBar.h>
00053 
00054 
00055 namespace PLearn {
00056 using namespace std;
00057 
00058 PLEARN_IMPLEMENT_OBJECT(
00059     MemoryStressTest,
00060     "Test memory leaks in Python embedding.",
00061     "Perform a large number of Python/C++ conversions to detect memory\n"
00062     "leaks (best run under valgrind or other leak detector)\n"
00063 );
00064 
00066 // MemoryStressTest //
00068 MemoryStressTest::MemoryStressTest():
00069     N(10000)
00070 {
00071     // ...
00072 
00073     // ### You may (or not) want to call build_() to finish building the object
00074     // ### (doing so assumes the parent classes' build_() have been called too
00075     // ### in the parent classes' constructors, something that you must ensure)
00076 }
00077 
00079 // build //
00081 void MemoryStressTest::build()
00082 {
00083     inherited::build();
00084     build_();
00085 }
00086 
00088 // makeDeepCopyFromShallowCopy //
00090 void MemoryStressTest::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00091 {
00092     inherited::makeDeepCopyFromShallowCopy(copies);
00093 
00094     // ### Call deepCopyField on all "pointer-like" fields 
00095     // ### that you wish to be deepCopied rather than 
00096     // ### shallow-copied.
00097     // ### ex:
00098     // deepCopyField(trainvec, copies);
00099 
00100     // ### Remove this line when you have fully implemented this method.
00101     PLERROR("MemoryStressTest::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!");
00102 }
00103 
00105 // declareOptions //
00107 void MemoryStressTest::declareOptions(OptionList& ol)
00108 {
00109     // ### Declare all of this object's options here
00110     // ### For the "flags" of each option, you should typically specify  
00111     // ### one of OptionBase::buildoption, OptionBase::learntoption or 
00112     // ### OptionBase::tuningoption. Another possible flag to be combined with
00113     // ### is OptionBase::nosave
00114 
00115     declareOption(ol, "N", &MemoryStressTest::N, OptionBase::buildoption,
00116         "Number of iterations to perform.");
00117 
00118     // Now call the parent class' declareOptions
00119     inherited::declareOptions(ol);
00120 }
00121 
00123 // build_ //
00125 void MemoryStressTest::build_()
00126 {
00127     // ### This method should do the real building of the object,
00128     // ### according to set 'options', in *any* situation. 
00129     // ### Typical situations include:
00130     // ###  - Initial building of an object from a few user-specified options
00131     // ###  - Building of a "reloaded" object: i.e. from the complete set of all serialised options.
00132     // ###  - Updating or "re-building" of an object after a few "tuning" options have been modified.
00133     // ### You should assume that the parent class' build_() has already been called.
00134 }
00135 
00136 string MemoryStressTest::python_code =
00137 "import sys\n"
00138 "#from numarray import *\n"
00139 "from numpy import *\n"
00140 "\n"
00141 "def nullary():\n"
00142 "    pass\n"
00143 "\n"
00144 "def unary_int(x):\n"
00145 "    assert isinstance(x,int)\n"
00146 "    return x\n"
00147 "\n"
00148 "def unary_long(x):\n"
00149 "    assert isinstance(x,long)\n"
00150 "    return x\n"
00151 "\n"
00152 "def unary_float(x):\n"
00153 "    assert isinstance(x,float)\n"
00154 "    return x\n"
00155 "\n"
00156 "def unary_str(x):\n"
00157 "    assert isinstance(x,str)\n"
00158 "    return x\n"
00159 "\n"
00160 "def unary_vec(x):\n"
00161 "    #assert isinstance(x,numarraycore.NumArray) and len(x.shape) == 1\n"
00162 "    assert isinstance(x,ndarray) and len(x.shape) == 1\n"
00163 "    return x\n"
00164 "\n"
00165 "def unary_mat(x):\n"
00166 "    #assert isinstance(x,numarraycore.NumArray) and len(x.shape) == 2\n"
00167 "    assert isinstance(x,ndarray) and len(x.shape) == 2\n"
00168 "    return x\n"
00169 "\n"
00170 "def unary_list_str(x):\n"
00171 "    assert isinstance(x,list)\n"
00172 "    return x\n"
00173 "\n"
00174 "def unary_dict(x):\n"
00175 "    assert isinstance(x,dict)\n"
00176 "    return x\n"
00177 "\n"
00178 "def binary(a,b):\n"
00179 "    return a,b\n"
00180 "\n"
00181 "def ternary(a,b,c):\n"
00182 "    return a,b,c\n"
00183 "\n"
00184 "def quaternary(a,b,c,d):\n"
00185 "    return a,b,c,d\n"
00186 ;
00187 
00188 
00189 void MemoryStressTest::nullary(const PythonCodeSnippet* python)
00190 {
00191     python->invoke("nullary");
00192 }
00193 
00194 void MemoryStressTest::unary(const PythonCodeSnippet* python)
00195 {
00196     int i       = python->invoke("unary_int", 42).as<int>();
00197     unsigned long long l
00198                 = python->invoke("unary_long", 18446744073709551615ULL).as<unsigned long long>();
00199     double d    = python->invoke("unary_float", 42.01).as<double>();
00200     string s    = python->invoke("unary_str", "Hello").as<string>();
00201 
00202     i = i;
00203     l = l;
00204     d = d;
00205 
00206     Vec v;
00207     string str_v = "[2,3,5,7,11,13,17,19,23]";
00208     PStream is = openString(str_v, PStream::plearn_ascii);
00209     is >> v;
00210     Mat m(3,3);
00211     m.toVec() << v;
00212 
00213     Vec py_vec = python->invoke("unary_vec", v).as<Vec>();
00214     Mat py_mat = python->invoke("unary_mat", m).as<Mat>();
00215 
00216     TVec<string> tvs;
00217     string str_tvs = "[\"Cela\", \"est\", \"juste\", \"et\", \"bon\"]";
00218     PStream is_tvs = openString(str_tvs, PStream::plearn_ascii);
00219     is_tvs >> tvs;
00220     vector<string> vecs(tvs.begin(), tvs.end());
00221 
00222     TVec<string> py_tvs    = python->invoke("unary_list_str", tvs).as< TVec<string> >();
00223     vector<string> py_vecs = python->invoke("unary_list_str", vecs).as< vector<string> >();
00224 
00225     map<string,int64_t> mapsd;
00226     string str_mapsd = "{ Oui:16 il:32 est:64 juste:128 et:256 bon:512 }";
00227     PStream is_mapsd = openString(str_mapsd, PStream::plearn_ascii);
00228     is_mapsd >> mapsd;
00229 
00230     map<string,int64_t> py_mapsd = python->invoke("unary_dict", mapsd).as< map<string,int64_t> >();
00231 }
00232 
00233 void MemoryStressTest::binary(const PythonCodeSnippet* python)
00234 {
00235     TVec<int> v = python->invoke("binary",2,4).as< TVec<int> >();
00236 }
00237 
00238 void MemoryStressTest::ternary(const PythonCodeSnippet* python)
00239 {
00240     TVec<int> v = python->invoke("ternary",2,4,8).as< TVec<int> >();
00241 }
00242 
00243 void MemoryStressTest::quaternary(const PythonCodeSnippet* python)
00244 {
00245     TVec<int> v = python->invoke("quaternary",2,4,8,16).as< TVec<int> >();
00246 }
00247 
00249 // perform //
00251 void MemoryStressTest::perform()
00252 {
00253     PP<PythonCodeSnippet> python = new PythonCodeSnippet(python_code);
00254     python->build();
00255 
00256     ProgressBar pb("Invoking Python Functions", N);
00257     
00258     for (int i=0 ; i<N ; ++i) {
00259         pb.update(i);
00260         
00261         nullary(python);
00262         unary(python);
00263         binary(python);
00264         ternary(python);
00265         quaternary(python);
00266     }
00267 }
00268 
00269 } // end of namespace PLearn
00270 
00271 
00272 /*
00273   Local Variables:
00274   mode:c++
00275   c-basic-offset:4
00276   c-file-style:"stroustrup"
00277   c-file-offsets:((innamespace . 0)(inline-open . 0))
00278   indent-tabs-mode:nil
00279   fill-column:79
00280   End:
00281 */
00282 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines