[Libreoffice-commits] core.git: 75 commits - config_host.mk.in configure.ac officecfg/registry RepositoryExternal.mk Repository.mk RepositoryModule_host.mk sc/CppunitTest_sc_ucalc.mk sc/inc sc/Library_scfilt.mk sc/Library_sc.mk sc/Library_scopencl.mk sc/Module_sc.mk sc/source sc/uiconfig sc/workben

Markus Mohrhard markus.mohrhard at googlemail.com
Thu Sep 19 08:12:09 PDT 2013


 Repository.mk                                            |    1 
 RepositoryExternal.mk                                    |   17 
 RepositoryModule_host.mk                                 |    2 
 config_host.mk.in                                        |    2 
 configure.ac                                             |   52 
 officecfg/registry/schema/org/openoffice/Office/Calc.xcs |   14 
 sc/CppunitTest_sc_ucalc.mk                               |    3 
 sc/Library_sc.mk                                         |   10 
 sc/Library_scfilt.mk                                     |    2 
 sc/Library_scopencl.mk                                   |   48 
 sc/Module_sc.mk                                          |    6 
 sc/inc/calcconfig.hxx                                    |    4 
 sc/inc/document.hxx                                      |    2 
 sc/inc/formulagroup.hxx                                  |    8 
 sc/inc/pch/precompiled_scopencl.cxx                      |   12 
 sc/inc/pch/precompiled_scopencl.hxx                      |   31 
 sc/inc/platforminfo.hxx                                  |   45 
 sc/source/core/opencl/clcc/clew.cxx                      |  326 ++
 sc/source/core/opencl/clcc/clew.h                        | 1318 +++++++++++
 sc/source/core/opencl/formulagroupcl.cxx                 |  184 -
 sc/source/core/opencl/oclkernels.hxx                     |    5 
 sc/source/core/opencl/openclwrapper.cxx                  | 1700 ++++++++-------
 sc/source/core/opencl/openclwrapper.hxx                  |  287 +-
 sc/source/core/tool/calcconfig.cxx                       |    7 
 sc/source/core/tool/formulagroup.cxx                     |  168 +
 sc/source/core/tool/formulaopt.cxx                       |   42 
 sc/source/core/tool/platforminfo.cxx                     |   21 
 sc/source/filter/excel/excform.cxx                       |   92 
 sc/source/filter/excel/impop.cxx                         |   83 
 sc/source/filter/excel/read.cxx                          |   16 
 sc/source/filter/ftools/clkernelthread.cxx               |   28 
 sc/source/filter/inc/clkernelthread.hxx                  |   26 
 sc/source/filter/inc/excform.hxx                         |    4 
 sc/source/filter/inc/imp_op.hxx                          |   31 
 sc/source/filter/inc/workbookhelper.hxx                  |    2 
 sc/source/filter/oox/workbookhelper.cxx                  |   23 
 sc/source/filter/oox/worksheetfragment.cxx               |    9 
 sc/source/ui/app/scmod.cxx                               |    3 
 sc/source/ui/optdlg/calcoptionsdlg.cxx                   |  140 +
 sc/source/ui/optdlg/calcoptionsdlg.hxx                   |   26 
 sc/uiconfig/scalc/ui/formulacalculationoptions.ui        |  211 +
 sc/workben/opencl/platform_detect.cxx                    |   72 
 42 files changed, 3906 insertions(+), 1177 deletions(-)

New commits:
commit da06f0fd15ae3ba2447f01b952a579c92a8a67d4
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Sep 19 17:02:10 2013 +0200

    fix windows build with pch

diff --git a/sc/inc/pch/precompiled_scopencl.cxx b/sc/inc/pch/precompiled_scopencl.cxx
new file mode 100644
index 0000000..85d15b4
--- /dev/null
+++ b/sc/inc/pch/precompiled_scopencl.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_scopencl.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/pch/precompiled_scopencl.hxx b/sc/inc/pch/precompiled_scopencl.hxx
new file mode 100644
index 0000000..b4cc3cf
--- /dev/null
+++ b/sc/inc/pch/precompiled_scopencl.hxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh . It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed. All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+*/
+
+#include "formula/vectortoken.hxx"
+#include "sal/config.h"
+#include <boost/scoped_array.hpp>
+#include <cmath>
+#include <config_folders.h>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/digest.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit ba1e90f444df55055e34fde6ae58bfe65c6a57bb
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Sep 18 18:09:02 2013 -0400

    "what!?" - Let's not say that...
    
    Change-Id: I1c9c2a62b2a1ede08fb2f27f541b501dc3ce7b2f

diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 4c49461..0c34957 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -142,8 +142,6 @@ void ImportExcel::Formula(
                     GetXFRangeBuffer().SetXF(aScPos, nXF);
                     SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell);
                 }
-                else
-                    fprintf(stdout, "ImportExcel::Formula:   what!?\n");
             }
             else
             {
commit f13f659bf16210b10697d3f422dcb1d26df76b41
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Sep 18 17:40:31 2013 -0400

    Work around another Excel bug with incorrect shared formula range.
    
    Take the start row position from the preceding formula record, rather
    than believing what's in the shared formula record. The latter can be
    wrong, and can be wrong often.
    
    Change-Id: I3a4da110727a7719e5f8cb3e6250c0e1bef04c64

diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index b557de5..4c49461 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -102,6 +102,9 @@ void ImportExcel::Formula4()
 void ImportExcel::Formula(
     const XclAddress& rXclPos, sal_uInt16 nXF, sal_uInt16 nFormLen, double fCurVal, bool bShrFmla)
 {
+    if (!nFormLen)
+        return;
+
     ScAddress aScPos( ScAddress::UNINITIALIZED );
     if (!GetAddressConverter().ConvertAddress(aScPos, rXclPos, GetCurrScTab(), true))
         // Conversion failed.
@@ -116,22 +119,39 @@ void ImportExcel::Formula(
     if (bShrFmla)
     {
         // This is a shared formula. Get the token array from the shared formula pool.
-        ScFormulaCellGroupRef xGroup = pFormConv->GetSharedFormula(maStrm, aScPos.Col(), nFormLen);
-        if (xGroup)
+        SCCOL nSharedCol;
+        SCROW nSharedRow;
+        if (pFormConv->ReadSharedFormulaPosition(maStrm, nSharedCol, nSharedRow))
         {
-            if (xGroup->mnStart == aScPos.Row())
-                // Generate code for the top cell only.
-                xGroup->compileCode(rDoc.getDoc(), aScPos, formula::FormulaGrammar::GRAM_DEFAULT);
-
-            ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, xGroup);
-            rDoc.getDoc().EnsureTable(aScPos.Tab());
-            rDoc.setFormulaCell(aScPos, pCell);
-            xGroup->mnLength = aScPos.Row() - xGroup->mnStart + 1;
-            pCell->SetNeedNumberFormat(false);
-            if (!rtl::math::isNan(fCurVal))
-                pCell->SetResultDouble(fCurVal);
-
-            GetXFRangeBuffer().SetXF(aScPos, nXF);
+            ScAddress aRefPos(aScPos.Col(), nSharedRow, GetCurrScTab());
+            ScFormulaCellGroupRef xGroup = pFormConv->GetSharedFormula(aRefPos);
+            if (xGroup)
+            {
+                // Make sure the this one follows immediately below another shared formula cell.
+                LastFormula* pLast = GetLastFormula(aScPos.Col());
+                if (pLast && pLast->mpCell && pLast->mnRow == (aScPos.Row()-1))
+                {
+                    ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, xGroup);
+                    rDoc.getDoc().EnsureTable(aScPos.Tab());
+                    rDoc.setFormulaCell(aScPos, pCell);
+                    xGroup->mnLength = aScPos.Row() - xGroup->mnStart + 1;
+                    pCell->SetNeedNumberFormat(false);
+                    if (!rtl::math::isNan(fCurVal))
+                        pCell->SetResultDouble(fCurVal);
+
+                    GetXFRangeBuffer().SetXF(aScPos, nXF);
+                    SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell);
+                }
+                else
+                    fprintf(stdout, "ImportExcel::Formula:   what!?\n");
+            }
+            else
+            {
+                // Shared formula not found even though it's clearly a shared formula.
+                // The cell will be created in the following shared formula
+                // record.
+                SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, NULL);
+            }
             return;
         }
     }
@@ -158,6 +178,7 @@ void ImportExcel::Formula(
         pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, pResult);
         rDoc.getDoc().EnsureTable(aScPos.Tab());
         rDoc.setFormulaCell(aScPos, pCell);
+        SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell);
     }
     else
     {
@@ -1692,30 +1713,30 @@ const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType )
     return pErgebnis;
 }
 
-ScFormulaCellGroupRef ExcelToSc::GetSharedFormula( XclImpStream& aIn, SCCOL nCol, sal_Size nFormulaLen )
+bool ExcelToSc::ReadSharedFormulaPosition( XclImpStream& rStrm, SCCOL& rCol, SCROW& rRow )
 {
-    if (!nFormulaLen)
-        return ScFormulaCellGroupRef();
-
-    aIn.PushPosition();
+    rStrm.PushPosition();
 
     sal_uInt8 nOp;
-    aIn >> nOp;
+    rStrm >> nOp;
 
     if (nOp != 0x01)   // must be PtgExp token.
     {
-        aIn.PopPosition();
-        return ScFormulaCellGroupRef();
+        rStrm.PopPosition();
+        return false;
     }
 
-    sal_uInt16 nLeftCol, nRow;
-    aIn >> nRow >> nLeftCol;
-
-    ScAddress aRefPos(nCol, nRow, GetCurrScTab());
-    ScFormulaCellGroupRef xGroup = GetOldRoot().pShrfmlaBuff->Find(aRefPos);
+    sal_uInt16 nRow, nCol;
+    rStrm >> nRow >> nCol;
+    rStrm.PopPosition();
+    rCol = nCol;
+    rRow = nRow;
+    return true;
+}
 
-    aIn.PopPosition();
-    aIn.Ignore(nFormulaLen);
+ScFormulaCellGroupRef ExcelToSc::GetSharedFormula( const ScAddress& rRefPos )
+{
+    ScFormulaCellGroupRef xGroup = GetOldRoot().pShrfmlaBuff->Find(rRefPos);
     return xGroup;
 }
 
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index 16c4ac5..a06aac1 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -114,8 +114,10 @@ ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ):
     maStrm( rStrm, GetRoot() ),
     aIn( maStrm ),
     maScOleSize( ScAddress::INITIALIZE_INVALID ),
+    mpLastFormula(NULL),
     mnLastRefIdx( 0 ),
     mnIxfeIndex( 0 ),
+    mnLastRecId(0),
     mbBiff2HasXfs(false),
     mbBiff2HasXfsValid(false),
     mbRunCLKernelThread(true)
@@ -165,6 +167,31 @@ ImportExcel::~ImportExcel( void )
     delete pFormConv;
 }
 
+void ImportExcel::SetLastFormula( SCCOL nCol, SCROW nRow, double fVal, sal_uInt16 nXF, ScFormulaCell* pCell )
+{
+    LastFormulaMapType::iterator it = maLastFormulaCells.find(nCol);
+    if (it == maLastFormulaCells.end())
+    {
+        std::pair<LastFormulaMapType::iterator, bool> r =
+            maLastFormulaCells.insert(
+                LastFormulaMapType::value_type(nCol, LastFormula()));
+        it = r.first;
+    }
+
+    it->second.mnCol = nCol;
+    it->second.mnRow = nRow;
+    it->second.mpCell = pCell;
+    it->second.mfValue = fVal;
+    it->second.mnXF = nXF;
+
+    mpLastFormula = &it->second;
+}
+
+ImportExcel::LastFormula* ImportExcel::GetLastFormula( SCCOL nCol )
+{
+    LastFormulaMapType::iterator it = maLastFormulaCells.find(nCol);
+    return it == maLastFormulaCells.end() ? NULL : &it->second;
+}
 
 void ImportExcel::ReadFileSharing()
 {
@@ -815,6 +842,21 @@ void ImportExcel::Standardwidth( void )
 
 void ImportExcel::Shrfmla( void )
 {
+    switch (mnLastRecId)
+    {
+        case EXC_ID2_FORMULA:
+        case EXC_ID3_FORMULA:
+        case EXC_ID4_FORMULA:
+            // This record MUST immediately follow a FORMULA record.
+        break;
+        default:
+            return;
+    }
+
+    if (!mpLastFormula)
+        // The last FORMULA record should have left this data.
+        return;
+
     sal_uInt16              nFirstRow, nLastRow, nLenExpr;
     sal_uInt8               nFirstCol, nLastCol;
 
@@ -829,13 +871,37 @@ void ImportExcel::Shrfmla( void )
     pFormConv->Reset();
     pFormConv->Convert( pErgebnis, maStrm, nLenExpr, true, FT_SharedFormula );
 
-
     OSL_ENSURE( pErgebnis, "+ImportExcel::Shrfmla(): ScTokenArray is NULL!" );
 
-    pExcRoot->pShrfmlaBuff->Store( ScRange( static_cast<SCCOL>(nFirstCol),
-                static_cast<SCROW>(nFirstRow), GetCurrScTab(),
-                static_cast<SCCOL>(nLastCol), static_cast<SCROW>(nLastRow),
-                GetCurrScTab()), *pErgebnis );
+    // The range in this record can be erroneous especially the row range.
+    // Use the row from the last FORMULA record as the start row.  The end row
+    // will be adjusted by the formula cells that follow.
+    SCCOL nCol1 = nFirstCol;
+    SCCOL nCol2 = nLastCol;
+    SCROW nRow1 = mpLastFormula->mnRow;
+
+    pExcRoot->pShrfmlaBuff->Store(
+        ScRange(nCol1, nRow1, GetCurrScTab(), nCol2, nRow1, GetCurrScTab()), *pErgebnis);
+
+    // Create formula cell for the last formula record.
+
+    ScAddress aPos(nCol1, nRow1, GetCurrScTab());
+    ScFormulaCellGroupRef xGroup = pExcRoot->pShrfmlaBuff->Find(aPos);
+    if (xGroup)
+    {
+        ScDocumentImport& rDoc = GetDocImport();
+        xGroup->compileCode(rDoc.getDoc(), aPos, formula::FormulaGrammar::GRAM_DEFAULT);
+
+        ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, xGroup);
+        rDoc.getDoc().EnsureTable(aPos.Tab());
+        rDoc.setFormulaCell(aPos, pCell);
+        pCell->SetNeedNumberFormat(false);
+        if (!rtl::math::isNan(mpLastFormula->mfValue))
+            pCell->SetResultDouble(mpLastFormula->mfValue);
+
+        GetXFRangeBuffer().SetXF(aPos, mpLastFormula->mnXF);
+        mpLastFormula->mpCell = pCell;
+    }
 }
 
 
@@ -1181,6 +1247,8 @@ void ImportExcel::NeueTabelle( void )
     }
 
     pExcRoot->pShrfmlaBuff->Clear();
+    maLastFormulaCells.clear();
+    mpLastFormula = NULL;
 
     InitializeTable( nTab );
 
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index 14396f6..610db55 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -630,7 +630,6 @@ FltError ImportExcel::Read( void )
                         case 0x0223: Externname34(); break; // EXTERNNAME   [  34 ]
                         case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345]
                         case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
-                        case 0x04BC: Shrfmla(); break;      // SHRFMLA      [    5]
                     }
                 }
             }
@@ -654,6 +653,7 @@ FltError ImportExcel::Read( void )
                     case EXC_ID2_FORMULA:
                     case EXC_ID3_FORMULA:
                     case EXC_ID4_FORMULA:       Formula25(); break;
+                    case EXC_ID_SHRFMLA: Shrfmla(); break;
                     case 0x0A:  Eof(); eAkt = Z_Biff5E;                 break;
                     case 0x14:
                     case 0x15:  rPageSett.ReadHeaderFooter( maStrm );   break;
@@ -833,7 +833,9 @@ FltError ImportExcel8::Read( void )
     std::vector<OUString> aCodeNames;
     std::vector < SCTAB > nTabsWithNoCodeName;
 
-    while( eAkt != EXC_STATE_END )
+    sal_uInt16 nRecId = 0;
+
+    for (; eAkt != EXC_STATE_END; mnLastRecId = nRecId)
     {
         if( eAkt == EXC_STATE_BEFORE_SHEET )
         {
@@ -937,7 +939,7 @@ FltError ImportExcel8::Read( void )
         if( eAkt != EXC_STATE_SHEET_PRE && eAkt != EXC_STATE_GLOBALS_PRE )
             pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos );
 
-        sal_uInt16 nRecId = aIn.GetRecId();
+        nRecId = aIn.GetRecId();
 
         /*  #i39464# Ignore records between USERSVIEWBEGIN and USERSVIEWEND
             completely (user specific view settings). Otherwise view settings
@@ -1145,7 +1147,6 @@ FltError ImportExcel8::Read( void )
                     case EXC_ID2_ARRAY:
                     case EXC_ID3_ARRAY: Array34(); break;      // ARRAY        [  34    ]
                     case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345   ]
-                    case EXC_ID_SHRFMLA: Shrfmla(); break;      // SHRFMLA      [    5   ]
                     case 0x0867: SheetProtection(); break; // SHEETPROTECTION
                 }
             }
@@ -1179,6 +1180,7 @@ FltError ImportExcel8::Read( void )
                     case EXC_ID2_FORMULA:
                     case EXC_ID3_FORMULA:
                     case EXC_ID4_FORMULA:       Formula25();            break;
+                    case EXC_ID_SHRFMLA:        Shrfmla();              break;
                     case 0x000C:    Calccount();            break;  // CALCCOUNT
                     case 0x0010:    Delta();                break;  // DELTA
                     case 0x0011:    Iteration();            break;  // ITERATION
diff --git a/sc/source/filter/inc/excform.hxx b/sc/source/filter/inc/excform.hxx
index 0e2004c..11254a0 100644
--- a/sc/source/filter/inc/excform.hxx
+++ b/sc/source/filter/inc/excform.hxx
@@ -63,7 +63,9 @@ public:
 
     void                GetDummy( const ScTokenArray*& );
     const ScTokenArray* GetBoolErr( XclBoolError );
-    ScFormulaCellGroupRef GetSharedFormula( XclImpStream& rStrm, SCCOL nCol, sal_Size nFormulaLen );
+
+    bool ReadSharedFormulaPosition( XclImpStream& rStrm, SCCOL& rCol, SCROW& rRow );
+    ScFormulaCellGroupRef GetSharedFormula( const ScAddress& rRefPos );
 
     static void         SetError( ScFormulaCell& rCell, const ConvErr eErr );
 
diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx
index 6e44f31..7c58395 100644
--- a/sc/source/filter/inc/imp_op.hxx
+++ b/sc/source/filter/inc/imp_op.hxx
@@ -35,7 +35,7 @@
 
 #include <boost/shared_ptr.hpp>
 #include <boost/ptr_container/ptr_vector.hpp>
-
+#include <boost/unordered_map.hpp>
 
 class SvStream;
 
@@ -82,6 +82,16 @@ private:
 class ImportExcel : public ImportTyp, protected XclImpRoot
 {
 protected:
+    struct LastFormula
+    {
+        SCCOL mnCol;
+        SCROW mnRow;
+        double mfValue;
+        sal_uInt16 mnXF;
+        ScFormulaCell* mpCell;
+    };
+    typedef boost::unordered_map<SCCOL, LastFormula> LastFormulaMapType;
+
     rtl::Reference<sc::CLBuildKernelThread> mxCLKernelThread;
 
     static const double     fExcToTwips;        // Umrechnung 1/256 Zeichen -> Twips
@@ -104,11 +114,14 @@ protected:
     typedef boost::ptr_vector< XclImpOutlineDataBuffer > XclImpOutlineListBuffer;
     XclImpOutlineListBuffer* pOutlineListBuffer;
 
+    LastFormulaMapType maLastFormulaCells; // Keep track of last formula cells in each column.
+    LastFormula* mpLastFormula;
+
     sal_Int16               mnLastRefIdx;
     sal_uInt16              mnIxfeIndex;        /// Current XF identifier from IXFE record.
+    sal_uInt16 mnLastRecId;
 
     SCTAB                   nBdshtTab;          // Counter fuer Boundsheet
-    ScFormulaCell*          pLastFormCell;      // fuer String-Records
 
     sal_Bool                    bTabTruncated;      // wenn Bereichsueberschreitung zum
                                                 //  Abschneiden von Zellen fuehrt
@@ -117,6 +130,9 @@ protected:
     bool mbBiff2HasXfsValid:1; /// False = mbBiff2HasXfs is undetermined yet.
     bool mbRunCLKernelThread:1;
 
+    void SetLastFormula( SCCOL nCol, SCROW nRow, double fVal, sal_uInt16 nXF, ScFormulaCell* pCell );
+    LastFormula* GetLastFormula( SCCOL nCol );
+
     // Record-Funktionen
     void                    ReadFileSharing();
 
commit dbedabaa44d2fda306cd4b5bb51d192fc1058794
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Sep 18 16:47:15 2013 +0200

    fix storing of open cl device in configuration files
    
    Change-Id: Icc343b55fe40c430b87d2e4c98701d78c61e3a96

diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
index 25fe724..4c583a4 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
@@ -1344,12 +1344,12 @@
           </info>
           <value>true</value>
         </prop>
-        <prop oor:name="OpenCLAutoDevice" oor:type="xs:string" oor:nillable="false">
+        <prop oor:name="OpenCLDevice" oor:type="xs:string" oor:nillable="false">
           <!-- UIHints: Tools - Options  Spreadsheet  Formula -->
           <info>
             <desc>The Device ID of the OpenCL device selected if OpenCLAutoSelect is false</desc>
           </info>
-          <value></value>
+          <value/>
         </prop>
       </group>
       <group oor:name="Syntax">
diff --git a/sc/source/core/tool/formulaopt.cxx b/sc/source/core/tool/formulaopt.cxx
index f649927..1ce5e09 100644
--- a/sc/source/core/tool/formulaopt.cxx
+++ b/sc/source/core/tool/formulaopt.cxx
@@ -216,7 +216,7 @@ Sequence<OUString> ScFormulaCfg::GetPropertyNames()
         "Load/ODFRecalcMode",            // SCFORMULAOPT_ODF_RECALC
         "Calculation/OpenCL",            // SCFORMULAOPT_OPENCL_ENABLED
         "Calculation/OpenCLAutoSelect",  // SCFORMULAOPT_OPENCL_AUTOSELECT
-        "Calculation/OpenCLAutoDevice"   // SCFORMULAOPT_OPENCL_DEVICE
+        "Calculation/OpenCLDevice"   // SCFORMULAOPT_OPENCL_DEVICE
     };
     Sequence<OUString> aNames(SCFORMULAOPT_COUNT);
     OUString* pNames = aNames.getArray();
@@ -428,6 +428,7 @@ void ScFormulaCfg::UpdateFromProperties( const Sequence<OUString>& aNames )
                     pValues[nProp] >>= aOpenCLDevice;
                     GetCalcConfig().maOpenCLDevice = aOpenCLDevice;
                 }
+                break;
                 default:
                     ;
                 }
@@ -540,6 +541,8 @@ void ScFormulaCfg::Commit()
             {
                 sal_Bool bVal = GetCalcConfig().mbOpenCLAutoSelect;
                 pValues[nProp] <<= bVal;
+                sc::FormulaGroupInterpreter::switchOpenCLDevice(
+                        GetCalcConfig().maOpenCLDevice, bVal);
             }
             break;
             case SCFORMULAOPT_OPENCL_DEVICE:
commit 5d0b4a5ae3806c4816e1fbe39514cbf52adfb229
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Sep 18 16:26:08 2013 +0200

    small fixes for broken code
    
    Change-Id: I77afc818d5575523077328042ac9418f521edc9c

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index d4cf1b7..d273463 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -251,8 +251,8 @@ std::vector<boost::shared_ptr<osl::File> > OpenclDevice::binaryGenerated( const
             }
         }
     }
-    return aGeneratedFiles;
 
+    return aGeneratedFiles;
 }
 
 int OpenclDevice::writeBinaryToFile( const OString& rFileName, const char* binary, size_t numBytes )
@@ -270,7 +270,6 @@ int OpenclDevice::writeBinaryToFile( const OString& rFileName, const char* binar
     assert(numBytes == nBytesWritten);
 
     return 1;
-
 }
 
 int OpenclDevice::generatBinFromKernelSource( cl_program program, const char * clFileName )
@@ -414,9 +413,7 @@ int OpenclDevice::cachedOfKernerPrg( const GPUEnv *gpuEnvCached, const char * cl
 int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 {
     cl_int clStatus = 0;
-    size_t length;
     int binary_status, idx;
-    cl_uint numDevices;
     const char* filename = "kernel.cl";
     fprintf(stderr, "compileKernelFile ... \n");
     if ( cachedOfKernerPrg(gpuInfo, filename) == 1 )
@@ -426,6 +423,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 
     idx = gpuInfo->mnFileCount;
 
+    cl_uint numDevices;
     clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_NUM_DEVICES,
             sizeof(numDevices), &numDevices, NULL );
     CHECK_OPENCL( clStatus, "clGetContextInfo" );
@@ -437,6 +435,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
     if (aGeneratedFiles.size() == numDevices)
     {
         bBinaryExisted = true;
+        boost::scoped_array<size_t> length(new size_t[numDevices]);
         boost::scoped_array<unsigned char*> pBinary(new unsigned char*[numDevices]);
         for(size_t i = 0; i < numDevices; ++i)
         {
@@ -448,7 +447,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
             if(nSize != nBytesRead)
                 assert(false);
 
-            length = nBytesRead;
+            length[i] = nBytesRead;
 
             pBinary[i] = binary;
         }
@@ -469,7 +468,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 
         fprintf(stderr, "Create kernel from binary\n");
         gpuInfo->mpArryPrograms[idx] = clCreateProgramWithBinary( gpuInfo->mpContext,numDevices,
-                                           mpArryDevsID.get(), &length, (const unsigned char**) pBinary.get(),
+                                           mpArryDevsID.get(), length.get(), (const unsigned char**) pBinary.get(),
                                            &binary_status, &clStatus );
         if(clStatus != CL_SUCCESS)
         {
@@ -515,6 +514,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 
     if ( clStatus != CL_SUCCESS )
     {
+        size_t length;
         printf ("BuildProgram error!\n");
         if ( !gpuInfo->mnIsUserCreated )
         {
commit 68035ffc3e94af0c3cef600a65fa301efd3045af
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Sep 18 16:21:43 2013 +0200

    select maximum one opencl device
    
    Change-Id: If06caaa6b39131359ffc81fadad200c8cf8fe24a

diff --git a/sc/source/ui/optdlg/calcoptionsdlg.cxx b/sc/source/ui/optdlg/calcoptionsdlg.cxx
index 9607fb6..eefb7f6 100644
--- a/sc/source/ui/optdlg/calcoptionsdlg.cxx
+++ b/sc/source/ui/optdlg/calcoptionsdlg.cxx
@@ -204,6 +204,8 @@ void ScCalcOptionsDialog::fillOpenclList()
 
     OUString aStoredDevice = maConfig.maOpenCLDevice;
 
+    SvTreeListEntry* pSelectedEntry = NULL;
+
     sc::FormulaGroupInterpreter::fillOpenCLInfo(maPlatformInfo);
     for(std::vector<sc::OpenclPlatformInfo>::iterator it = maPlatformInfo.begin(),
             itEnd = maPlatformInfo.end(); it != itEnd; ++it)
@@ -215,13 +217,18 @@ void ScCalcOptionsDialog::fillOpenclList()
             SvTreeListEntry* pEntry = mpOpenclInfoList->InsertEntry(aDeviceId);
             if(aDeviceId == aStoredDevice)
             {
-                mpOpenclInfoList->GetModel()->GetView(0)->Select(pEntry);
+                pSelectedEntry = pEntry;
             }
             pEntry->SetUserData(&(*itr));
         }
     }
 
     mpOpenclInfoList->SetUpdateMode(true);
+    mpOpenclInfoList->GetModel()->GetView(0)->SelectAll(false, false);
+    if(pSelectedEntry)
+    {
+        mpOpenclInfoList->GetModel()->GetView(0)->Select(pSelectedEntry);
+    }
     SelectedDeviceChanged();
 }
 
commit 268c33e1b32a407fb3db66c41cbb9bf15e9422a2
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Sep 18 13:06:16 2013 +0200

    fix memory leak
    
    Change-Id: If1afe59bc5bb40bb3fff4c74b863c6d77e006cc5

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 0fe2220..d4cf1b7 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -475,10 +475,10 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
         {
             // something went wrong, fall back to compiling from source
             bBinaryExisted = false;
-            for(size_t i = 0; i < numDevices; ++i)
-            {
-                delete[] pBinary[i];
-            }
+        }
+        for(size_t i = 0; i < numDevices; ++i)
+        {
+            delete[] pBinary[i];
         }
     }
 
commit 77201250b47a267b4474a394d748c934acfaef39
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Sep 18 13:05:31 2013 +0200

    fall back to compiling from source if binary failed
    
    Change-Id: I8e8d8fb5b1da18c44e1537f97317d4e5b57c47b6

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index f469aac..0fe2220 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -473,14 +473,16 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
                                            &binary_status, &clStatus );
         if(clStatus != CL_SUCCESS)
         {
+            // something went wrong, fall back to compiling from source
+            bBinaryExisted = false;
             for(size_t i = 0; i < numDevices; ++i)
             {
                 delete[] pBinary[i];
             }
         }
-        CHECK_OPENCL( clStatus, "clCreateProgramWithBinary" );
     }
-    else
+
+    if(!bBinaryExisted)
     {
         // create a CL program using the kernel source
         fprintf(stderr, "Create kernel from source\n");
commit ee19608f940d0985f4ba4cd918bc53aaf25f0301
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Sep 18 12:45:37 2013 +0200

    void* is dangerous
    
    no idea how that ever worked
    
    Change-Id: Ie14c86a241a2fa7e1963385987245cd0ee965fcf

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 1a19451..f469aac 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -437,17 +437,19 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
     if (aGeneratedFiles.size() == numDevices)
     {
         bBinaryExisted = true;
-        boost::scoped_array<char*> pBinary(new char*[numDevices]);
+        boost::scoped_array<unsigned char*> pBinary(new unsigned char*[numDevices]);
         for(size_t i = 0; i < numDevices; ++i)
         {
             sal_uInt64 nSize;
             aGeneratedFiles[i]->getSize(nSize);
-            char* binary = new char[nSize];
+            unsigned char* binary = new unsigned char[nSize];
             sal_uInt64 nBytesRead;
             aGeneratedFiles[i]->read(binary, nSize, nBytesRead);
             if(nSize != nBytesRead)
                 assert(false);
 
+            length = nBytesRead;
+
             pBinary[i] = binary;
         }
 
@@ -467,7 +469,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 
         fprintf(stderr, "Create kernel from binary\n");
         gpuInfo->mpArryPrograms[idx] = clCreateProgramWithBinary( gpuInfo->mpContext,numDevices,
-                                           mpArryDevsID.get(), &length, (const unsigned char**) &pBinary,
+                                           mpArryDevsID.get(), &length, (const unsigned char**) pBinary.get(),
                                            &binary_status, &clStatus );
         if(clStatus != CL_SUCCESS)
         {
commit 5b0bc1bee668ab670044ecd564c84583c261c07e
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Sep 17 19:31:41 2013 +0200

    use $UserInstallation/cache to cache opencl kernels
    
    Change-Id: I2ba1fb6172cfd0c725a45d4506b46e8f04a33093

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 45dedc2..1a19451 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -18,6 +18,7 @@
 #include <boost/scoped_array.hpp>
 
 #include "sal/config.h"
+#include <osl/file.hxx>
 #include "oclkernels.hxx"
 
 #include <stdio.h>
commit a321536cc682e98ad677deae3fa36b4dd25520f5
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Sep 17 23:04:54 2013 +0200

    read the binary files from the cached folder
    
    Change-Id: Ifc5084a3d8ef661e3b3fca7fbc76e1c0c62b2056

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 1ca38fd..45dedc2 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -18,7 +18,6 @@
 #include <boost/scoped_array.hpp>
 
 #include "sal/config.h"
-#include <osl/file.hxx>
 #include "oclkernels.hxx"
 
 #include <stdio.h>
@@ -216,45 +215,42 @@ OString createFileName(cl_device_id deviceId, const char* clFileName)
 
 }
 
-int OpenclDevice::binaryGenerated( const char * clFileName, FILE ** fhandle )
+std::vector<boost::shared_ptr<osl::File> > OpenclDevice::binaryGenerated( const char * clFileName, cl_context context )
 {
-    unsigned int i = 0;
-    cl_int clStatus;
-    int status = 0;
-    FILE *fd = NULL;
     cl_uint numDevices=0;
-    if ( getenv("SC_OPENCLCPU") )
-    {
-        clStatus = clGetDeviceIDs(gpuEnv.mpPlatformID, // platform
-                                  CL_DEVICE_TYPE_CPU,  // device_type for CPU device
-                                  0,                   // num_entries
-                                  NULL,                // devices ID
-                                  &numDevices);
-    }
-    else
-    {
-        clStatus = clGetDeviceIDs(gpuEnv.mpPlatformID, // platform
-                                  CL_DEVICE_TYPE_GPU,  // device_type for GPU device
-                                  0,                   // num_entries
-                                  NULL,                // devices ID
-                                  &numDevices);
-    }
-    CHECK_OPENCL( clStatus, "clGetDeviceIDs" );
 
-    for ( i = 0; i < numDevices; i++ )
+    std::vector<boost::shared_ptr<osl::File> > aGeneratedFiles;
+    cl_int clStatus = clGetContextInfo( context, CL_CONTEXT_NUM_DEVICES,
+            sizeof(numDevices), &numDevices, NULL );
+
+    if(clStatus != CL_SUCCESS)
+        return aGeneratedFiles;
+
+
+    // grab the handles to all of the devices in the context.
+    boost::scoped_array<cl_device_id> mpArryDevsID(new cl_device_id[numDevices]);
+    clStatus = clGetContextInfo( context, CL_CONTEXT_DEVICES,
+            sizeof( cl_device_id ) * numDevices, mpArryDevsID.get(), NULL );
+
+    if(clStatus != CL_SUCCESS)
+        return aGeneratedFiles;
+
+    for ( size_t i = 0; i < numDevices; i++ )
     {
-        if ( gpuEnv.mpArryDevsID[i] != 0 )
+        if ( mpArryDevsID[i] != 0 )
         {
             OString fileName = createFileName(gpuEnv.mpArryDevsID[i], clFileName);
-            fd = fopen( fileName.getStr(), "rb" );
-            status = ( fd != NULL ) ? 1 : 0;
+            osl::File* pNewFile = new osl::File(rtl::OStringToOUString(fileName, RTL_TEXTENCODING_UTF8));
+            if(pNewFile->open(osl_File_OpenFlag_Read) == osl::FileBase::E_None)
+                aGeneratedFiles.push_back(boost::shared_ptr<osl::File>(pNewFile));
+            else
+            {
+                delete pNewFile;
+                break;
+            }
         }
     }
-    if ( fd != NULL )
-    {
-        *fhandle = fd;
-    }
-    return status;
+    return aGeneratedFiles;
 
 }
 
@@ -418,10 +414,8 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 {
     cl_int clStatus = 0;
     size_t length;
-    char *binary;
-    int b_error, binary_status, binaryExisted, idx;
+    int binary_status, idx;
     cl_uint numDevices;
-    FILE *fd;
     const char* filename = "kernel.cl";
     fprintf(stderr, "compileKernelFile ... \n");
     if ( cachedOfKernerPrg(gpuInfo, filename) == 1 )
@@ -431,49 +425,57 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 
     idx = gpuInfo->mnFileCount;
 
-    binaryExisted = 0;
-    if ( ( binaryExisted = binaryGenerated( filename, &fd ) ) == 1 )
-    {
-        clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_NUM_DEVICES,
-                       sizeof(numDevices), &numDevices, NULL );
-        CHECK_OPENCL( clStatus, "clGetContextInfo" );
+    clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_NUM_DEVICES,
+            sizeof(numDevices), &numDevices, NULL );
+    CHECK_OPENCL( clStatus, "clGetContextInfo" );
 
-        boost::scoped_array<cl_device_id> mpArryDevsID(new cl_device_id[numDevices]);
+    std::vector<boost::shared_ptr<osl::File> > aGeneratedFiles = binaryGenerated(
+            filename, gpuInfo->mpContext );
 
-        b_error = 0;
-        length = 0;
-        b_error |= fseek( fd, 0, SEEK_END ) < 0;
-        b_error |= ( length = ftell(fd) ) <= 0;
-        b_error |= fseek( fd, 0, SEEK_SET ) < 0;
-        if ( b_error )
-        {
-            return 0;
-        }
-
-        binary = (char*) malloc( length + 2 );
-        if ( !binary )
+    bool bBinaryExisted = false;
+    if (aGeneratedFiles.size() == numDevices)
+    {
+        bBinaryExisted = true;
+        boost::scoped_array<char*> pBinary(new char*[numDevices]);
+        for(size_t i = 0; i < numDevices; ++i)
         {
-            return 0;
+            sal_uInt64 nSize;
+            aGeneratedFiles[i]->getSize(nSize);
+            char* binary = new char[nSize];
+            sal_uInt64 nBytesRead;
+            aGeneratedFiles[i]->read(binary, nSize, nBytesRead);
+            if(nSize != nBytesRead)
+                assert(false);
+
+            pBinary[i] = binary;
         }
 
-        memset( binary, 0, length + 2 );
-        b_error |= fread( binary, 1, length, fd ) != length;
-
-
-        fclose( fd );
-        fd = NULL;
         // grab the handles to all of the devices in the context.
+        boost::scoped_array<cl_device_id> mpArryDevsID(new cl_device_id[numDevices]);
         clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_DEVICES,
                        sizeof( cl_device_id ) * numDevices, mpArryDevsID.get(), NULL );
+
+        if(clStatus != CL_SUCCESS)
+        {
+            for(size_t i = 0; i < numDevices; ++i)
+            {
+                delete[] pBinary[i];
+            }
+        }
         CHECK_OPENCL( clStatus, "clGetContextInfo" );
 
         fprintf(stderr, "Create kernel from binary\n");
         gpuInfo->mpArryPrograms[idx] = clCreateProgramWithBinary( gpuInfo->mpContext,numDevices,
-                                           mpArryDevsID.get(), &length, (const unsigned char**) &binary,
+                                           mpArryDevsID.get(), &length, (const unsigned char**) &pBinary,
                                            &binary_status, &clStatus );
+        if(clStatus != CL_SUCCESS)
+        {
+            for(size_t i = 0; i < numDevices; ++i)
+            {
+                delete[] pBinary[i];
+            }
+        }
         CHECK_OPENCL( clStatus, "clCreateProgramWithBinary" );
-
-        free( binary );
     }
     else
     {
@@ -558,7 +560,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 
     strcpy( gpuEnv.mArryKnelSrcFile[idx], filename );
 
-    if ( binaryExisted == 0 )
+    if ( !bBinaryExisted )
         generatBinFromKernelSource( gpuEnv.mpArryPrograms[idx], filename );
 
     gpuInfo->mnFileCount += 1;
diff --git a/sc/source/core/opencl/openclwrapper.hxx b/sc/source/core/opencl/openclwrapper.hxx
index 7bcf5c4..c81c313 100644
--- a/sc/source/core/opencl/openclwrapper.hxx
+++ b/sc/source/core/opencl/openclwrapper.hxx
@@ -13,6 +13,9 @@
 #include <config_features.h>
 #include <formula/opcode.hxx>
 #include <sal/detail/log.h>
+#include <osl/file.hxx>
+#include <vector>
+#include <boost/shared_ptr.hpp>
 #include <cassert>
 #include "platforminfo.hxx"
 
@@ -174,7 +177,7 @@ public:
     static int cachedOfKernerPrg( const GPUEnv *gpuEnvCached, const char * clFileName );
     static int generatBinFromKernelSource( cl_program program, const char * clFileName );
     static int writeBinaryToFile( const OString& rName, const char* birary, size_t numBytes );
-    static int binaryGenerated( const char * clFileName, FILE ** fhandle );
+    static std::vector<boost::shared_ptr<osl::File> > binaryGenerated( const char * clFileName, cl_context context);
     static int compileKernelFile( const char *filename, GPUEnv *gpuInfo, const char *buildOption );
 
     static int initOpenclAttr( OpenCLEnv * env );
commit 7f7c930dcd9195a05fb133ebb393dcbd37e2f66c
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Sep 17 20:30:53 2013 +0200

    replace one more file write with location in profile directory
    
    Change-Id: I1774f66d018923c6f892d21acf8a81330628cd98

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 98ef0d2..1ca38fd 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -419,10 +419,9 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
     cl_int clStatus = 0;
     size_t length;
     char *binary;
-    const char *source;
     int b_error, binary_status, binaryExisted, idx;
     cl_uint numDevices;
-    FILE *fd, *fd1;
+    FILE *fd;
     const char* filename = "kernel.cl";
     fprintf(stderr, "compileKernelFile ... \n");
     if ( cachedOfKernerPrg(gpuInfo, filename) == 1 )
@@ -432,8 +431,6 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 
     idx = gpuInfo->mnFileCount;
 
-    source = kernel_src;
-
     binaryExisted = 0;
     if ( ( binaryExisted = binaryGenerated( filename, &fd ) ) == 1 )
     {
@@ -483,8 +480,9 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
         // create a CL program using the kernel source
         fprintf(stderr, "Create kernel from source\n");
         size_t source_size[1];
-        source_size[0] = strlen( source );
-        gpuEnv.mpArryPrograms[idx] = clCreateProgramWithSource( gpuEnv.mpContext, 1, &source,
+
+        source_size[0] = strlen( kernel_src );
+        gpuEnv.mpArryPrograms[idx] = clCreateProgramWithSource( gpuEnv.mpContext, 1, &kernel_src,
                                          source_size, &clStatus);
         CHECK_OPENCL( clStatus, "clCreateProgramWithSource" );
     }
@@ -544,12 +542,16 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
             return 0;
         }
 
-        fd1 = fopen( "kernel-build.log", "w+" );
-        if ( fd1 != NULL )
-        {
-            fwrite( buildLog.get(), sizeof(char), length, fd1 );
-            fclose( fd1 );
-        }
+        OString aBuildLogFileURL = maCacheFolder + "kernel-build.log";
+        osl::File aBuildLogFile(rtl::OStringToOUString(aBuildLogFileURL, RTL_TEXTENCODING_UTF8));
+        osl::FileBase::RC status = aBuildLogFile.open(
+                osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
+
+        if(status != osl::FileBase::E_None)
+            return 0;
+
+        sal_uInt64 nBytesWritten = 0;
+        aBuildLogFile.write( buildLog.get(), length, nBytesWritten );
 
         return 0;
     }
commit 7d3cca2471777a26f90c15aa435c8b50ad6133ca
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Sep 17 19:49:20 2013 +0200

    fix another memory leak
    
    Change-Id: I6761bcc137934b02815ce10d43f3bc9bee7a1b90

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 2ec2046..98ef0d2 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -418,7 +418,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 {
     cl_int clStatus = 0;
     size_t length;
-    char *buildLog = NULL, *binary;
+    char *binary;
     const char *source;
     int b_error, binary_status, binaryExisted, idx;
     cl_uint numDevices;
@@ -526,20 +526,17 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
             printf("opencl create build log fail\n");
             return 0;
         }
-        buildLog = (char*) malloc( length );
-        if ( buildLog == (char*) NULL )
-        {
-            return 0;
-        }
+
+        boost::scoped_array<char> buildLog(new char[length]);
         if ( !gpuInfo->mnIsUserCreated )
         {
             clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpArryDevsID[0],
-                           CL_PROGRAM_BUILD_LOG, length, buildLog, &length );
+                           CL_PROGRAM_BUILD_LOG, length, buildLog.get(), &length );
         }
         else
         {
             clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpDevID,
-                           CL_PROGRAM_BUILD_LOG, length, buildLog, &length );
+                           CL_PROGRAM_BUILD_LOG, length, buildLog.get(), &length );
         }
         if ( clStatus != CL_SUCCESS )
         {
@@ -550,11 +547,10 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
         fd1 = fopen( "kernel-build.log", "w+" );
         if ( fd1 != NULL )
         {
-            fwrite( buildLog, sizeof(char), length, fd1 );
+            fwrite( buildLog.get(), sizeof(char), length, fd1 );
             fclose( fd1 );
         }
 
-        free( buildLog );
         return 0;
     }
 
commit 29e0843f323c54f9dea9e763a7300bf5fcc2014b
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Sep 17 19:36:09 2013 +0200

    fix another memory leak
    
    Change-Id: I31359f121fa858dfc1868d74a2f827e5332592c3

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 3610659..2ec2046 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -420,10 +420,8 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
     size_t length;
     char *buildLog = NULL, *binary;
     const char *source;
-    size_t source_size[1];
     int b_error, binary_status, binaryExisted, idx;
     cl_uint numDevices;
-    cl_device_id *mpArryDevsID;
     FILE *fd, *fd1;
     const char* filename = "kernel.cl";
     fprintf(stderr, "compileKernelFile ... \n");
@@ -436,7 +434,6 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
 
     source = kernel_src;
 
-    source_size[0] = strlen( source );
     binaryExisted = 0;
     if ( ( binaryExisted = binaryGenerated( filename, &fd ) ) == 1 )
     {
@@ -444,11 +441,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
                        sizeof(numDevices), &numDevices, NULL );
         CHECK_OPENCL( clStatus, "clGetContextInfo" );
 
-        mpArryDevsID = (cl_device_id*) malloc( sizeof(cl_device_id) * numDevices );
-        if ( mpArryDevsID == NULL )
-        {
-            return 0;
-        }
+        boost::scoped_array<cl_device_id> mpArryDevsID(new cl_device_id[numDevices]);
 
         b_error = 0;
         length = 0;
@@ -474,23 +467,23 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption )
         fd = NULL;
         // grab the handles to all of the devices in the context.
         clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_DEVICES,
-                       sizeof( cl_device_id ) * numDevices, mpArryDevsID, NULL );
+                       sizeof( cl_device_id ) * numDevices, mpArryDevsID.get(), NULL );
         CHECK_OPENCL( clStatus, "clGetContextInfo" );
 
         fprintf(stderr, "Create kernel from binary\n");
         gpuInfo->mpArryPrograms[idx] = clCreateProgramWithBinary( gpuInfo->mpContext,numDevices,
-                                           mpArryDevsID, &length, (const unsigned char**) &binary,
+                                           mpArryDevsID.get(), &length, (const unsigned char**) &binary,
                                            &binary_status, &clStatus );
         CHECK_OPENCL( clStatus, "clCreateProgramWithBinary" );
 
         free( binary );
-        free( mpArryDevsID );
-        mpArryDevsID = NULL;
     }
     else
     {
         // create a CL program using the kernel source
         fprintf(stderr, "Create kernel from source\n");
+        size_t source_size[1];
+        source_size[0] = strlen( source );
         gpuEnv.mpArryPrograms[idx] = clCreateProgramWithSource( gpuEnv.mpContext, 1, &source,
                                          source_size, &clStatus);
         CHECK_OPENCL( clStatus, "clCreateProgramWithSource" );
commit 0093de75d1e2545803e63b35663cbed7bfc5b64f
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Sep 17 19:31:41 2013 +0200

    use $UserInstallation/cache to cache opencl kernels
    
    Change-Id: I2ba1fb6172cfd0c725a45d4506b46e8f04a33093

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 684abe6..3610659 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -7,14 +7,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <config_folders.h>
+
 #include "openclwrapper.hxx"
 
 #include <rtl/ustring.hxx>
 #include <rtl/strbuf.hxx>
 #include <rtl/digest.h>
+#include <rtl/bootstrap.hxx>
 #include <boost/scoped_array.hpp>
 
 #include "sal/config.h"
+#include <osl/file.hxx>
 #include "oclkernels.hxx"
 
 #include <stdio.h>
@@ -76,9 +80,20 @@ OString generateHashForSource()
     return aBuffer.makeStringAndClear();
 }
 
+OString getCacheFolder()
+{
+    OUString url("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/cache/");
+    rtl::Bootstrap::expandMacros(url);
+
+    osl::Directory::create(url);
+
+    return rtl::OUStringToOString(url, RTL_TEXTENCODING_UTF8);
+}
+
 }
 
 OString OpenclDevice::maSourceHash = generateHashForSource();
+OString OpenclDevice::maCacheFolder = getCacheFolder();
 
 int OpenclDevice::releaseOpenclRunEnv()
 {
@@ -195,7 +210,8 @@ OString createFileName(cl_device_id deviceId, const char* clFileName)
     char deviceName[DEVICE_NAME_LENGTH] = {0};
     clGetDeviceInfo(deviceId, CL_DEVICE_NAME,
             sizeof(deviceName), deviceName, NULL);
-    return fileName + "-" + deviceName + "-" + OpenclDevice::maSourceHash + ".bin";
+    return OpenclDevice::maCacheFolder + fileName + "-" +
+        deviceName + "-" + OpenclDevice::maSourceHash + ".bin";
 }
 
 }
@@ -242,17 +258,19 @@ int OpenclDevice::binaryGenerated( const char * clFileName, FILE ** fhandle )
 
 }
 
-int OpenclDevice::writeBinaryToFile( const OString& rFileName, const char* birary, size_t numBytes )
+int OpenclDevice::writeBinaryToFile( const OString& rFileName, const char* binary, size_t numBytes )
 {
-    FILE *output = NULL;
-    output = fopen( rFileName.getStr(), "wb" );
-    if ( output == NULL )
-    {
+    osl::File file(rtl::OStringToOUString(rFileName, RTL_TEXTENCODING_UTF8));
+    osl::FileBase::RC status = file.open(
+            osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
+
+    if(status != osl::FileBase::E_None)
         return 0;
-    }
 
-    fwrite( birary, sizeof(char), numBytes, output );
-    fclose( output );
+    sal_uInt64 nBytesWritten = 0;
+    file.write( binary, numBytes, nBytesWritten );
+
+    assert(numBytes == nBytesWritten);
 
     return 1;
 
diff --git a/sc/source/core/opencl/openclwrapper.hxx b/sc/source/core/opencl/openclwrapper.hxx
index 5a89e6b..7bcf5c4 100644
--- a/sc/source/core/opencl/openclwrapper.hxx
+++ b/sc/source/core/opencl/openclwrapper.hxx
@@ -163,6 +163,8 @@ public:
     static GPUEnv gpuEnv;
     static int isInited;
     static OString maSourceHash;
+    static OString maCacheFolder;
+
     static int registOpenclKernel();
     static int releaseOpenclRunEnv();
     static int initOpenclRunEnv( GPUEnv *gpu );
commit 8f0a558f580516a4810552060c3da69ff6e2aa23
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 23:34:11 2013 -0400

    In xlsx, a better heuristic is based on worksheet dimension.
    
    And start OpenCL kernel compilation right away if the dimension is
    large enough to make the sheet import slow.
    
    Change-Id: Iee3e8dc1f0cb64eb1d8778db19c6edd73e971136

diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index cc8a50a..21e383f 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -65,7 +65,6 @@ void FormulaBuffer::finalizeImport()
         FormulaDataMap::iterator cellIt = maCellFormulas.find( nTab );
         if ( cellIt != maCellFormulas.end() )
         {
-            compileOpenCLKernels();
             applyCellFormulas( cellIt->second );
         }
 
diff --git a/sc/source/filter/oox/worksheetfragment.cxx b/sc/source/filter/oox/worksheetfragment.cxx
index b8ad658..93cacd7 100644
--- a/sc/source/filter/oox/worksheetfragment.cxx
+++ b/sc/source/filter/oox/worksheetfragment.cxx
@@ -511,7 +511,16 @@ void WorksheetFragment::importDimension( const AttributeList& rAttribs )
         be set. If the cell A1 exists, the used area will be updated while
         importing the cell. */
     if( (aRange.EndColumn > 0) || (aRange.EndRow > 0) )
+    {
         extendUsedArea( aRange );
+
+        // Start pre-compiling OpenCL kernels if we have a large number of
+        // cells to import.  The current threshold is 100,000.
+        double fCellCount = aRange.EndColumn - aRange.StartColumn + 1.0;
+        fCellCount *= aRange.EndRow - aRange.StartRow + 1.0;
+        if (fCellCount > 100000.0)
+            compileOpenCLKernels();
+    }
 }
 
 void WorksheetFragment::importSheetFormatPr( const AttributeList& rAttribs )
commit 05f6ae8779f9be59b1262bcbb98a74b6383c0c18
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 20:57:48 2013 -0400

    Be explicit on what kind of "kernels" we are compiling.
    
    Change-Id: I2415a192d98b94e86c08c138ad39cfdbf36ea283

diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index c6f32ac..e7c13cd 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -56,7 +56,7 @@ class SC_DLLPUBLIC FormulaGroupInterpreter
     static FormulaGroupInterpreter *getStatic();
     static void fillOpenCLInfo(std::vector<OpenclPlatformInfo>& rPlatforms);
     static void switchOpenCLDevice(const OUString& rDeviceId, bool bAutoSelect);
-    static void compileKernels();
+    static void compileOpenCLKernels();
 
     virtual ScMatrixRef inverseMatrix(const ScMatrix& rMat) = 0;
     virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) = 0;
diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index a311179..ab7076d 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1095,9 +1095,9 @@ SAL_DLLPUBLIC_EXPORT bool SAL_CALL switchOpenClDevice(const OUString* pDeviceId,
     return sc::opencl::switchOpenclDevice(pDeviceId, bAutoSelect);
 }
 
-SAL_DLLPUBLIC_EXPORT void compileKernels(const OUString* pDeviceId)
+SAL_DLLPUBLIC_EXPORT void compileOpenCLKernels(const OUString* pDeviceId)
 {
-    sc::opencl::compileKernels(pDeviceId);
+    sc::opencl::compileOpenCLKernels(pDeviceId);
 }
 
 }
diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 78d3bef..684abe6 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -2744,7 +2744,7 @@ bool switchOpenclDevice(const OUString* pDevice, bool bAutoSelect)
     return !OpenclDevice::initOpenclRunEnv(0);
 }
 
-void compileKernels(const OUString* pDeviceId)
+void compileOpenCLKernels(const OUString* pDeviceId)
 {
     if (!pDeviceId)
         return;
diff --git a/sc/source/core/opencl/openclwrapper.hxx b/sc/source/core/opencl/openclwrapper.hxx
index dfa8fbb..5a89e6b 100644
--- a/sc/source/core/opencl/openclwrapper.hxx
+++ b/sc/source/core/opencl/openclwrapper.hxx
@@ -266,7 +266,7 @@ const std::vector<OpenclPlatformInfo>& fillOpenCLInfo();
  */
 bool switchOpenclDevice(const OUString* pDeviceId, bool bAutoSelect);
 
-void compileKernels(const OUString* pDeviceId);
+void compileOpenCLKernels(const OUString* pDeviceId);
 
 }}
 
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 6a20a0c..2f85ee5 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -338,7 +338,7 @@ typedef FormulaGroupInterpreter* (*__createFormulaGroupOpenCLInterpreter)(void);
 typedef size_t (*__getOpenCLPlatformCount)(void);
 typedef void (*__fillOpenCLInfo)(OpenclPlatformInfo*, size_t);
 typedef bool (*__switchOpenClDevice)(const OUString*, bool);
-typedef void (*__compileKernels)(const OUString*);
+typedef void (*__compileOpenCLKernels)(const OUString*);
 
 #endif
 
@@ -458,7 +458,7 @@ void FormulaGroupInterpreter::switchOpenCLDevice(const OUString& rDeviceId, bool
 #endif
 }
 
-void FormulaGroupInterpreter::compileKernels()
+void FormulaGroupInterpreter::compileOpenCLKernels()
 {
     const ScCalcConfig& rConfig = ScInterpreter::GetGlobalConfig();
     if (!rConfig.mbOpenCLEnabled)
@@ -469,11 +469,11 @@ void FormulaGroupInterpreter::compileKernels()
     if (!pModule)
         return;
 
-    oslGenericFunction fn = pModule->getFunctionSymbol("compileKernels");
+    oslGenericFunction fn = pModule->getFunctionSymbol("compileOpenCLKernels");
     if (!fn)
         return;
 
-    reinterpret_cast<__compileKernels>(fn)(&rConfig.maOpenCLDevice);
+    reinterpret_cast<__compileOpenCLKernels>(fn)(&rConfig.maOpenCLDevice);
 }
 
 void FormulaGroupInterpreter::generateRPNCode(ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rCode)
diff --git a/sc/source/filter/ftools/clkernelthread.cxx b/sc/source/filter/ftools/clkernelthread.cxx
index f6d8c63..dcb1e74 100644
--- a/sc/source/filter/ftools/clkernelthread.cxx
+++ b/sc/source/filter/ftools/clkernelthread.cxx
@@ -20,7 +20,7 @@ CLBuildKernelThread::~CLBuildKernelThread() {}
 
 void CLBuildKernelThread::execute()
 {
-    sc::FormulaGroupInterpreter::compileKernels();
+    sc::FormulaGroupInterpreter::compileOpenCLKernels();
 }
 
 }
commit d3236e2bdde1ff1211e65e64d22063c8228c68dc
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 20:53:24 2013 -0400

    Add a heuristic to avoid always pre-compile OpenCL kernels (for xls).
    
    If we still have 3 MB worth of stream to parse after the first formula
    record, we pre-compile OpenCL kernels in a separate thread.
    
    Change-Id: I129d95c26f26e4b1eb989bc2a1764a3f87f71fcb

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 2b2f8f7..78d3bef 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -2770,7 +2770,6 @@ void compileKernels(const OUString* pDeviceId)
         if (nStatus != CL_SUCCESS)
             r.mpKernel = NULL;
     }
-
 }
 
 }}
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 49ca6ca..b557de5 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -136,11 +136,19 @@ void ImportExcel::Formula(
         }
     }
 
-    if (!mxCLKernelThread.is())
+    if (mbRunCLKernelThread && !mxCLKernelThread.is())
     {
-        mxCLKernelThread.set(new sc::CLBuildKernelThread);
-        mxCLKernelThread->launch();
+        double fRemainSize = maStrm.GetSvStreamSize() - maStrm.GetSvStreamPos();
+        fRemainSize /= 1048576; // Switch to MB.
+        if (fRemainSize > 3.0)
+        {
+            // We still have more than 3MB of stream to parse. Start a thread to pre-compile OpenCL kernels.
+            mxCLKernelThread.set(new sc::CLBuildKernelThread);
+            mxCLKernelThread->launch();
+        }
+        mbRunCLKernelThread = false;
     }
+
     ConvErr eErr = pFormConv->Convert( pResult, maStrm, nFormLen, true, FT_CellFormula);
 
     ScFormulaCell* pCell = NULL;
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index e03980b..16c4ac5 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -116,8 +116,9 @@ ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ):
     maScOleSize( ScAddress::INITIALIZE_INVALID ),
     mnLastRefIdx( 0 ),
     mnIxfeIndex( 0 ),
-    mbBiff2HasXfs( false ),
-    mbBiff2HasXfsValid( false )
+    mbBiff2HasXfs(false),
+    mbBiff2HasXfsValid(false),
+    mbRunCLKernelThread(true)
 {
     nBdshtTab = 0;
 
diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx
index 613ae30..6e44f31 100644
--- a/sc/source/filter/inc/imp_op.hxx
+++ b/sc/source/filter/inc/imp_op.hxx
@@ -106,8 +106,6 @@ protected:
 
     sal_Int16               mnLastRefIdx;
     sal_uInt16              mnIxfeIndex;        /// Current XF identifier from IXFE record.
-    bool                    mbBiff2HasXfs;      /// Select XF formatting or direct formatting in BIFF2.
-    bool                    mbBiff2HasXfsValid; /// False = mbBiff2HasXfs is undetermined yet.
 
     SCTAB                   nBdshtTab;          // Counter fuer Boundsheet
     ScFormulaCell*          pLastFormCell;      // fuer String-Records
@@ -115,6 +113,10 @@ protected:
     sal_Bool                    bTabTruncated;      // wenn Bereichsueberschreitung zum
                                                 //  Abschneiden von Zellen fuehrt
 
+    bool mbBiff2HasXfs:1;      /// Select XF formatting or direct formatting in BIFF2.
+    bool mbBiff2HasXfsValid:1; /// False = mbBiff2HasXfs is undetermined yet.
+    bool mbRunCLKernelThread:1;
+
     // Record-Funktionen
     void                    ReadFileSharing();
 
commit 0881af7718a3a8591afa062b9dd446ca7193e86f
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 17:26:45 2013 -0400

    Oops this wasn't meant to be checked in.
    
    Change-Id: I6eccbd38a44dfaec66718df210884067beaaf30e

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 7bcd390..2b2f8f7 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -43,49 +43,6 @@
 
 #define DEVICE_NAME_LENGTH 1024
 
-
-#include <stdio.h>
-#include <string>
-#include <sys/time.h>
-
-namespace {
-
-class stack_printer
-{
-public:
-    explicit stack_printer(const char* msg) :
-        msMsg(msg)
-    {
-        fprintf(stdout, "%s: --begin\n", msMsg.c_str());
-        mfStartTime = getTime();
-    }
-
-    ~stack_printer()
-    {
-        double fEndTime = getTime();
-        fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime - mfStartTime));
-    }
-
-    void printTime(int line) const
-    {
-        double fEndTime = getTime();
-        fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime - mfStartTime));
-    }
-
-private:
-    double getTime() const
-    {
-        timeval tv;
-        gettimeofday(&tv, NULL);
-        return tv.tv_sec + tv.tv_usec / 1000000.0;
-    }
-
-    ::std::string msMsg;
-    double mfStartTime;
-};
-
-}
-
 using namespace std;
 
 namespace sc { namespace opencl {
@@ -2795,8 +2752,6 @@ void compileKernels(const OUString* pDeviceId)
     if (pDeviceId->isEmpty())
         return;
 
-    stack_printer __stack_printer__("sc/opencl::compileKernels");
-    fprintf(stdout, "opencl::compileKernels:   device = '%s'\n", rtl::OUStringToOString(*pDeviceId, RTL_TEXTENCODING_UTF8).getStr());
     if (!switchOpenclDevice(pDeviceId, false))
         return;
 
commit 6f0b9dd26f061594f93e8ee6cc59415a6e8583f0
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 17:22:38 2013 -0400

    Fix illegal memory access between malloc and memset.
    
    Change-Id: I6f040e48a1a60b8f4fc1f2424a24ff362de9a31e

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 139a219..a311179 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -455,66 +455,54 @@ double * agency::calculate( int nOclOp,int rowSize,OclCalc &ocl_calc,uint *npOcl
         {
             case ocAdd:
             {
-                unsigned int nDataSize = 0;
                 SourceData *temp = formulaInterprt->srdDataPop();
                 SourceData *temp2 = formulaInterprt->srdDataPop();
-                nDataSize = temp2->getDataSize();
                 dpLeftData = temp2->getDouleData();
                 dpRightData = temp->getDouleData();
-                nDataSize = temp2->getDataSize();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc( sizeof(double) * nDataSize );
+                rResult = (double *)malloc( sizeof(double) * rowSize );
                 memset(rResult,0,rowSize);
                 ocl_calc.oclHostArithmeticStash64Bits( "oclSignedAdd",dpLeftData,dpRightData,rResult,temp->getDataSize() );
-                formulaInterprt->srdDataPush( new SourceData( rResult,nDataSize ) );
+                formulaInterprt->srdDataPush( new SourceData( rResult,rowSize ) );
                 break;
             }
             case ocSub:
             {
-                unsigned int nDataSize = 0;
                 SourceData *temp = formulaInterprt->srdDataPop();
                 SourceData *temp2 = formulaInterprt->srdDataPop();
-                nDataSize = temp2->getDataSize();
                 dpLeftData = temp2->getDouleData();
                 dpRightData = temp->getDouleData();
-                nDataSize = temp2->getDataSize();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = ( double * )malloc( sizeof(double) * nDataSize );
+                rResult = ( double * )malloc( sizeof(double) * rowSize );
                 memset( rResult,0,rowSize );
                 ocl_calc.oclHostArithmeticStash64Bits( "oclSignedSub",dpLeftData,dpRightData,rResult,temp->getDataSize() );
-                formulaInterprt->srdDataPush( new SourceData(rResult,nDataSize) );
+                formulaInterprt->srdDataPush( new SourceData(rResult,rowSize) );
                 break;
             }
             case ocMul:
             {
-                unsigned int nDataSize = 0;
                 SourceData *temp = formulaInterprt->srdDataPop();
                 SourceData *temp2 = formulaInterprt->srdDataPop();
-                nDataSize = temp2->getDataSize();
                 dpLeftData = temp2->getDouleData();
                 dpRightData = temp->getDouleData();
-                nDataSize = temp2->getDataSize();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc( sizeof(double) * nDataSize );
+                rResult = (double *)malloc( sizeof(double) * rowSize );
                 memset( rResult,0,rowSize );
                 ocl_calc.oclHostArithmeticStash64Bits( "oclSignedMul",dpLeftData,dpRightData,rResult,temp->getDataSize() );
-                formulaInterprt->srdDataPush( new SourceData( rResult,nDataSize ) );
+                formulaInterprt->srdDataPush( new SourceData( rResult,rowSize ) );
                 break;
             }
             case ocDiv:
             {
-                unsigned int nDataSize = 0;
                 SourceData *temp = formulaInterprt->srdDataPop();
                 SourceData *temp2 = formulaInterprt->srdDataPop();
-                nDataSize = temp2->getDataSize();
                 dpLeftData = temp2->getDouleData();
                 dpRightData = temp->getDouleData();
-                nDataSize = temp2->getDataSize();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = ( double * )malloc( sizeof(double) * nDataSize );
+                rResult = ( double * )malloc( sizeof(double) * rowSize );
                 memset( rResult,0,rowSize );
                 ocl_calc.oclHostArithmeticStash64Bits( "oclSignedDiv",dpLeftData,dpRightData,rResult,temp->getDataSize() );
-                formulaInterprt->srdDataPush( new SourceData( rResult,nDataSize ) );
+                formulaInterprt->srdDataPush( new SourceData( rResult,rowSize ) );
                 break;
             }
             case ocMax:
@@ -567,66 +555,54 @@ double * agency::calculate( int nOclOp,int rowSize,OclCalc &ocl_calc,uint *npOcl
         {
             case ocAdd:
             {
-                unsigned int nDataSize = 0;
                 SourceData *temp = formulaInterprt->srdDataPop();
                 SourceData *temp2 = formulaInterprt->srdDataPop();
-                nDataSize = temp2->getDataSize();
                 dpLeftData = temp2->getDouleData();
                 dpRightData = temp->getDouleData();
-                nDataSize = temp2->getDataSize();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc( sizeof(double) * nDataSize );
+                rResult = (double *)malloc( sizeof(double) * rowSize );
                 memset(rResult,0,rowSize);
                 ocl_calc.oclHostArithmeticStash32Bits( "oclSignedAdd", dpLeftData, dpRightData, rResult, temp->getDataSize() );
-                formulaInterprt->srdDataPush( new SourceData(rResult, nDataSize) );
+                formulaInterprt->srdDataPush( new SourceData(rResult, rowSize) );
                 break;
             }
             case ocSub:
             {
-                unsigned int nDataSize = 0;
                 SourceData *temp = formulaInterprt->srdDataPop();
                 SourceData *temp2 = formulaInterprt->srdDataPop();
-                nDataSize = temp2->getDataSize();
                 dpLeftData = temp2->getDouleData();
                 dpRightData = temp->getDouleData();
-                nDataSize = temp2->getDataSize();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc( sizeof(double) * nDataSize );
+                rResult = (double *)malloc( sizeof(double) * rowSize );
                 memset( rResult, 0, rowSize );
                 ocl_calc.oclHostArithmeticStash32Bits( "oclSignedSub", dpLeftData, dpRightData, rResult, temp->getDataSize() );
-                formulaInterprt->srdDataPush( new SourceData( rResult,nDataSize ) );
+                formulaInterprt->srdDataPush( new SourceData( rResult, rowSize ) );
                 break;
             }
             case ocMul:
             {
-                unsigned int nDataSize = 0;
                 SourceData *temp = formulaInterprt->srdDataPop();
                 SourceData *temp2 = formulaInterprt->srdDataPop();
-                nDataSize = temp2->getDataSize();
                 dpLeftData = temp2->getDouleData();
                 dpRightData = temp->getDouleData();
-                nDataSize = temp2->getDataSize();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc(sizeof(double) * nDataSize );
+                rResult = (double *)malloc(sizeof(double) * rowSize );
                 memset( rResult, 0, rowSize );
                 ocl_calc.oclHostArithmeticStash32Bits( "oclSignedMul", dpLeftData, dpRightData, rResult, temp->getDataSize() );
-                formulaInterprt->srdDataPush( new SourceData( rResult, nDataSize ) );
+                formulaInterprt->srdDataPush( new SourceData( rResult, rowSize ) );
                 break;
             }
             case ocDiv:
             {
-                unsigned int nDataSize = 0;
                 SourceData *temp = formulaInterprt->srdDataPop();
                 SourceData *temp2 = formulaInterprt->srdDataPop();
-                nDataSize = temp2->getDataSize();
                 dpLeftData = temp2->getDouleData();
                 dpRightData = temp->getDouleData();
-                nDataSize = temp2->getDataSize();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc( sizeof(double) * nDataSize );
+                rResult = (double *)malloc( sizeof(double) * rowSize );
                 memset( rResult, 0, rowSize );
                 ocl_calc.oclHostArithmeticStash32Bits( "oclSignedDiv", dpLeftData, dpRightData, rResult, temp->getDataSize() );
-                formulaInterprt->srdDataPush( new SourceData(rResult, nDataSize) );
+                formulaInterprt->srdDataPush( new SourceData(rResult, rowSize) );
                 break;
             }
             case ocMax:
@@ -636,7 +612,7 @@ double * agency::calculate( int nOclOp,int rowSize,OclCalc &ocl_calc,uint *npOcl
                 nDataSize = temp->getDataSize();
                 dpOclSrcData = temp->getDouleData();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc(sizeof(double) * nDataSize );
+                rResult = (double *)malloc(sizeof(double) * rowSize );
                 memset(rResult,0,rowSize);
                 ocl_calc.oclHostFormulaStash32Bits( "oclFormulaMax", dpOclSrcData, npOclStartPos, npOclEndPos, rResult,nDataSize, rowSize );
                 formulaInterprt->srdDataPush( new SourceData( rResult, rowSize ) );
@@ -649,7 +625,7 @@ double * agency::calculate( int nOclOp,int rowSize,OclCalc &ocl_calc,uint *npOcl
                 nDataSize = temp->getDataSize();
                 dpOclSrcData = temp->getDouleData();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc( sizeof(double) * nDataSize );
+                rResult = (double *)malloc( sizeof(double) * rowSize );
                 memset( rResult, 0, rowSize );
                 ocl_calc.oclHostFormulaStash32Bits( "oclFormulaMin", dpOclSrcData, npOclStartPos, npOclEndPos, rResult, nDataSize, rowSize );
                 formulaInterprt->srdDataPush( new SourceData( rResult, rowSize) );
@@ -662,7 +638,7 @@ double * agency::calculate( int nOclOp,int rowSize,OclCalc &ocl_calc,uint *npOcl
                 nDataSize = temp->getDataSize();
                 dpOclSrcData = temp->getDouleData();
                 double *rResult = NULL; // Point to the output data from GPU
-                rResult = (double *)malloc( sizeof(double) * nDataSize );
+                rResult = (double *)malloc( sizeof(double) * rowSize );
                 memset( rResult, 0, rowSize);
                 ocl_calc.oclHostFormulaStash32Bits( "oclFormulaAverage", dpOclSrcData, npOclStartPos, npOclEndPos, rResult, nDataSize, rowSize );
                 formulaInterprt->srdDataPush( new SourceData( rResult, rowSize) );
diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 2b2f8f7..7bcd390 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -43,6 +43,49 @@
 
 #define DEVICE_NAME_LENGTH 1024
 
+
+#include <stdio.h>
+#include <string>
+#include <sys/time.h>
+
+namespace {
+
+class stack_printer
+{
+public:
+    explicit stack_printer(const char* msg) :
+        msMsg(msg)
+    {
+        fprintf(stdout, "%s: --begin\n", msMsg.c_str());
+        mfStartTime = getTime();
+    }
+
+    ~stack_printer()
+    {
+        double fEndTime = getTime();
+        fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime - mfStartTime));
+    }
+
+    void printTime(int line) const
+    {
+        double fEndTime = getTime();
+        fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime - mfStartTime));
+    }
+
+private:
+    double getTime() const
+    {
+        timeval tv;
+        gettimeofday(&tv, NULL);
+        return tv.tv_sec + tv.tv_usec / 1000000.0;
+    }
+
+    ::std::string msMsg;
+    double mfStartTime;
+};
+
+}
+
 using namespace std;
 
 namespace sc { namespace opencl {
@@ -2752,6 +2795,8 @@ void compileKernels(const OUString* pDeviceId)
     if (pDeviceId->isEmpty())
         return;
 
+    stack_printer __stack_printer__("sc/opencl::compileKernels");
+    fprintf(stdout, "opencl::compileKernels:   device = '%s'\n", rtl::OUStringToOString(*pDeviceId, RTL_TEXTENCODING_UTF8).getStr());
     if (!switchOpenclDevice(pDeviceId, false))
         return;
 
commit 732e0eabb3736f2a572500dab229efe3fc1fedd6
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 16:48:20 2013 -0400

    Bail out early on error.
    
    Change-Id: I1844284ff829f6af6c2cfe10935cfc1eef155deb

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 5697b1b..139a219 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -308,7 +308,14 @@ bool FormulaGroupInterpreterOpenCL::chooseFunction( OclCalc &ocl_calc, double *&
             pGroundWaterDataArray=NULL;
             delta = mdpSvdouble[0];
         }
-        ocl_calc.oclGroundWaterGroup( mnOperatorGroup,mnOperatorCount,pGroundWaterDataArray,pArrayToSubtractOneElementFrom,nSrcData,mnRowSize,delta,mnpOclStartPos,mnpOclEndPos,dpResult);
+
+        bool bSuccess = ocl_calc.oclGroundWaterGroup(
+            mnOperatorGroup, mnOperatorCount, pGroundWaterDataArray,
+            pArrayToSubtractOneElementFrom, nSrcData, mnRowSize, delta,
+            mnpOclStartPos, mnpOclEndPos, dpResult);
+
+        if (!bSuccess)
+            return false;
     }
     else if( isStockHistory() )
     {
@@ -332,14 +339,19 @@ bool FormulaGroupInterpreterOpenCL::chooseFunction( OclCalc &ocl_calc, double *&
             {
                 if (!ocl_calc.createFormulaBuf64Bits(nSrcDataSize, mnRowSize))
                     return false;
-                ocl_calc.mapAndCopy64Bits( dpOclSrcData,mnpOclStartPos,mnpOclEndPos,nSrcDataSize,mnRowSize );
-                ocl_calc.oclHostFormulaStatistics64Bits( mcHostName, dpResult, mnRowSize );
+                if (!ocl_calc.mapAndCopy64Bits(dpOclSrcData, mnpOclStartPos, mnpOclEndPos, nSrcDataSize, mnRowSize))
+                    return false;
+                if (!ocl_calc.oclHostFormulaStatistics64Bits(mcHostName, dpResult, mnRowSize))
+                    return false;
             }
             else
             {
-                ocl_calc.createFormulaBuf32Bits( nSrcDataSize, mnPositonLen );
-                ocl_calc.mapAndCopy32Bits( dpOclSrcData, mnpOclStartPos, mnpOclEndPos, nSrcDataSize, mnRowSize);
-                ocl_calc.oclHostFormulaStatistics32Bits( mcHostName, dpResult, mnRowSize );
+                if (!ocl_calc.createFormulaBuf32Bits(nSrcDataSize, mnPositonLen))
+                    return false;
+                if (!ocl_calc.mapAndCopy32Bits(dpOclSrcData, mnpOclStartPos, mnpOclEndPos, nSrcDataSize, mnRowSize))
+                    return false;
+                if (!ocl_calc.oclHostFormulaStatistics32Bits(mcHostName, dpResult, mnRowSize))
+                    return false;
             }
         }
     }
@@ -359,16 +371,21 @@ bool FormulaGroupInterpreterOpenCL::chooseFunction( OclCalc &ocl_calc, double *&
         {
             if ( ocl_calc.gpuEnv.mnKhrFp64Flag == 1 || ocl_calc.gpuEnv.mnAmdFp64Flag == 1 )
             {
-                ocl_calc.createArithmeticOptBuf64Bits( mnRowSize );
-                ocl_calc.mapAndCopy64Bits(dpLeftData,dpRightData,mnRowSize);
+                if (!ocl_calc.createArithmeticOptBuf64Bits(mnRowSize))
+                    return false;
+                if (!ocl_calc.mapAndCopy64Bits(dpLeftData, dpRightData, mnRowSize))
+                    return false;
                 if (!ocl_calc.oclHostArithmeticOperator64Bits(mcHostName, dpResult, mnRowSize))
                     return false;
             }
             else
             {
-                ocl_calc.createArithmeticOptBuf32Bits( mnRowSize );
-                ocl_calc.mapAndCopy32Bits(dpLeftData,dpRightData,mnRowSize);
-                ocl_calc.oclHostArithmeticOperator32Bits( mcHostName,dpResult,mnRowSize );
+                if (!ocl_calc.createArithmeticOptBuf32Bits(mnRowSize))
+                    return false;
+                if (!ocl_calc.mapAndCopy32Bits(dpLeftData, dpRightData, mnRowSize))
+                    return false;
+                if (!ocl_calc.oclHostArithmeticOperator32Bits(mcHostName, dpResult, mnRowSize))
+                    return false;
             }
         }
     }
@@ -396,15 +413,21 @@ bool FormulaGroupInterpreterOpenCL::chooseFunction( OclCalc &ocl_calc, double *&
         {
             if ( ocl_calc.gpuEnv.mnKhrFp64Flag == 1 || ocl_calc.gpuEnv.mnAmdFp64Flag == 1 )
             {
-                ocl_calc.createMoreColArithmeticBuf64Bits( j * mnRowSize, mnOperatorCount );
-                ocl_calc.mapAndCopyMoreColArithmetic64Bits( dpMoreColArithmetic, mnRowSize * j, mnOperatorGroup, mnOperatorCount );
-                ocl_calc.oclMoreColHostArithmeticOperator64Bits( mnRowSize, mnOperatorCount, dpResult,mnRowSize );
+                if (!ocl_calc.createMoreColArithmeticBuf64Bits(j * mnRowSize, mnOperatorCount))
+                    return false;
+                if (!ocl_calc.mapAndCopyMoreColArithmetic64Bits(dpMoreColArithmetic, mnRowSize * j, mnOperatorGroup, mnOperatorCount))
+                    return false;
+                if (!ocl_calc.oclMoreColHostArithmeticOperator64Bits(mnRowSize, mnOperatorCount, dpResult, mnRowSize))
+                    return false;
             }
             else
             {
-                ocl_calc.createMoreColArithmeticBuf32Bits( j* mnRowSize, mnOperatorCount );
-                ocl_calc.mapAndCopyMoreColArithmetic32Bits(dpMoreColArithmetic, mnRowSize * j, mnOperatorGroup, mnOperatorCount);
-                ocl_calc.oclMoreColHostArithmeticOperator32Bits( mnRowSize, mnOperatorCount, dpResult, mnRowSize );
+                if (!ocl_calc.createMoreColArithmeticBuf32Bits(j* mnRowSize, mnOperatorCount))
+                    return false;
+                if (!ocl_calc.mapAndCopyMoreColArithmetic32Bits(dpMoreColArithmetic, mnRowSize * j, mnOperatorGroup, mnOperatorCount))
+                    return false;
+                if (!ocl_calc.oclMoreColHostArithmeticOperator32Bits(mnRowSize, mnOperatorCount, dpResult, mnRowSize))
+                    return false;
             }
         }
     }
commit 18d80b5ec0a82e72e23558ca9b8e971ac35a7592
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 16:10:35 2013 -0400

    Wrong config option name.
    
    Change-Id: Ibbd2d9ed7ee20b8cc911bb5f3247bade617b7c74

diff --git a/sc/source/core/tool/formulaopt.cxx b/sc/source/core/tool/formulaopt.cxx
index 4c926e9..f649927 100644
--- a/sc/source/core/tool/formulaopt.cxx
+++ b/sc/source/core/tool/formulaopt.cxx
@@ -216,7 +216,7 @@ Sequence<OUString> ScFormulaCfg::GetPropertyNames()
         "Load/ODFRecalcMode",            // SCFORMULAOPT_ODF_RECALC
         "Calculation/OpenCL",            // SCFORMULAOPT_OPENCL_ENABLED
         "Calculation/OpenCLAutoSelect",  // SCFORMULAOPT_OPENCL_AUTOSELECT
-        "Calculation/OpenCLDevice"       // SCFORMULAOPT_OPENCL_DEVICE
+        "Calculation/OpenCLAutoDevice"   // SCFORMULAOPT_OPENCL_DEVICE
     };
     Sequence<OUString> aNames(SCFORMULAOPT_COUNT);
     OUString* pNames = aNames.getArray();
commit 80a4a753c5accfea756c4b357fc1586e8afbead8
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 15:56:38 2013 -0400

    Pre-compile OpenCL kernels during xlsx file load as well.
    
    Change-Id: Id31190b2a9eb496f146fbbeaaf8a223d46492a99

diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx
index e540ba0..9ea2353 100644
--- a/sc/source/filter/inc/workbookhelper.hxx
+++ b/sc/source/filter/inc/workbookhelper.hxx
@@ -275,6 +275,8 @@ public:
     /** Returns the codec helper that stores the encoder/decoder object. */
     BiffCodecHelper&    getCodecHelper() const;
 
+    void compileOpenCLKernels();
+
 private:
     WorkbookGlobals&    mrBookGlob;
 };
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 21e383f..cc8a50a 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -65,6 +65,7 @@ void FormulaBuffer::finalizeImport()
         FormulaDataMap::iterator cellIt = maCellFormulas.find( nTab );
         if ( cellIt != maCellFormulas.end() )
         {
+            compileOpenCLKernels();
             applyCellFormulas( cellIt->second );
         }
 
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 7a9a58f..9ae6fea 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -71,6 +71,8 @@
 #include "dbdata.hxx"
 #include "datauno.hxx"
 #include "globalnames.hxx"
+#include "clkernelthread.hxx"
+#include "rtl/ref.hxx"
 
 #include "formulabuffer.hxx"
 #include "vcl/mapmod.hxx"
@@ -223,6 +225,8 @@ public:
     /** Returns the codec helper that stores the encoder/decoder object. */
     inline BiffCodecHelper& getCodecHelper() { return *mxCodecHelper; }
 
+    void compileOpenCLKernels();
+
 private:
     /** Initializes some basic members and sets needed document properties. */
     void                initialize( bool bWorkbookFile );
@@ -253,6 +257,8 @@ private:
     typedef ::std::auto_ptr< PageSettingsConverter >    PageSettConvPtr;
     typedef ::std::auto_ptr< BiffCodecHelper >          BiffCodecHelperPtr;
 
+    rtl::Reference<sc::CLBuildKernelThread> mxCLKernelThread;
+
     OUString            maCellStyles;           /// Style family name for cell styles.
     OUString            maPageStyles;           /// Style family name for page styles.
     OUString            maCellStyleServ;        /// Service name for a cell style.
@@ -504,6 +510,15 @@ void WorkbookGlobals::useInternalChartDataTable( bool bInternal )
 
 // private --------------------------------------------------------------------
 
+void WorkbookGlobals::compileOpenCLKernels()
+{
+    if (mxCLKernelThread.is())
+        return;
+
+    mxCLKernelThread.set(new sc::CLBuildKernelThread);
+    mxCLKernelThread->launch();
+}
+
 void WorkbookGlobals::initialize( bool bWorkbookFile )
 {
     maCellStyles = "CellStyles";
@@ -634,6 +649,9 @@ void WorkbookGlobals::finalize()
         //ScDocShell::AfterXMLLoading() for ods
         getScDocument().SetInsertingFromOtherDoc(false);
         getScDocument().RebuildFormulaGroups();
+
+        if (mxCLKernelThread.is())
+            mxCLKernelThread->join();
     }
 }
 
@@ -949,6 +967,11 @@ BiffCodecHelper& WorkbookHelper::getCodecHelper() const
     return mrBookGlob.getCodecHelper();
 }
 
+void WorkbookHelper::compileOpenCLKernels()
+{
+    mrBookGlob.compileOpenCLKernels();
+}
+
 // ============================================================================
 
 } // namespace xls
commit 8f56dc0bf547c20404f98493e49dc88bf454a604
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 15:18:01 2013 -0400

    Compiler warning.
    
    Change-Id: Ibf3d21d2666b5c2504804141200ea0fcf9897565

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index 7a8b205..2b2f8f7 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -56,11 +56,14 @@ namespace {
 
 OString generateHashForSource()
 {
-    size_t nLength = strlen(kernel_src);
     sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_MD5];
+
+#ifndef NDEBUG
+    size_t nLength = strlen(kernel_src);
     rtlDigestError aError = rtl_digest_MD5(kernel_src, nLength,
             pBuffer, RTL_DIGEST_LENGTH_MD5);
     assert(aError == rtl_Digest_E_None);
+#endif
 
     OStringBuffer aBuffer;
     const char* pString = "0123456789ABCDEF";
commit 59d6f566be3229ff083a6157f575749ce2485bac
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 15:14:00 2013 -0400

    Let's treat oclMatrixSolve equally. No special treatment for this guy.
    
    Change-Id: I79d36ad7c95bf4cc8cd6bb4fd55dcedd5cd70684

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index ce0f662..7a8b205 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -125,7 +125,9 @@ const char* pKernelNames[] = {
     "oclMaxDiv",
     "oclAverageDiv"
     "oclMinDiv",
-    "oclSub"
+    "oclSub",
+
+    "oclMatrixSolve"
 };
 
 }
@@ -2341,20 +2343,22 @@ bool OclCalc::oclHostMatrixInverse64Bits( const char* aKernelName, double *dpOcl
     }
     clStatus = clEnqueueUnmapMemObject( kEnv.mpkCmdQueue, mpClmemLeftData, dpOclMatrixSrc, 0, NULL, NULL );
     CHECK_OPENCL( clStatus, "clEnqueueUnmapMemObject" );
-    cl_kernel kernel_solve = clCreateKernel( kEnv.mpkProgram, "oclMatrixSolve", &clStatus );
-    CHECK_OPENCL( clStatus, "clCreateKernel" );
-    clStatus = clSetKernelArg( kernel_solve, 0, sizeof(cl_mem), (void *)&mpClmemLeftData );
+    Kernel* pKernelMatrix = fetchKernel("oclMatrixSolve");
+    if (!pKernelMatrix)
+        return false;
+
+    clStatus = clSetKernelArg(pKernel->mpKernel, 0, sizeof(cl_mem), (void *)&mpClmemLeftData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
-    clStatus = clSetKernelArg( kernel_solve, 1, sizeof(cl_mem), (void *)&mpClmemRightData );
+    clStatus = clSetKernelArg(pKernel->mpKernel, 1, sizeof(cl_mem), (void *)&mpClmemRightData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
-    clStatus = clSetKernelArg( kernel_solve, 2, sizeof(cl_mem), (void *)&clpPData );
+    clStatus = clSetKernelArg(pKernel->mpKernel, 2, sizeof(cl_mem), (void *)&clpPData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
-    clStatus = clSetKernelArg( kernel_solve, 3, sizeof(cl_mem), (void *)&clpYData );
+    clStatus = clSetKernelArg(pKernel->mpKernel, 3, sizeof(cl_mem), (void *)&clpYData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
-    clStatus = clSetKernelArg( kernel_solve, 4, sizeof(cl_mem), (void *)&clpNData );
+    clStatus = clSetKernelArg(pKernel->mpKernel, 4, sizeof(cl_mem), (void *)&clpNData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
 
-    clStatus = clEnqueueNDRangeKernel( kEnv.mpkCmdQueue, kernel_solve, 1, NULL, global_work_size, NULL, 0, NULL, NULL );
+    clStatus = clEnqueueNDRangeKernel(kEnv.mpkCmdQueue, pKernel->mpKernel, 1, NULL, global_work_size, NULL, 0, NULL, NULL);
     CHECK_OPENCL( clStatus, "clEnqueueNDRangeKernel" );
     clFinish( kEnv.mpkCmdQueue );
     for ( uint i = 0; i < nDim; i++ )
@@ -2370,8 +2374,6 @@ bool OclCalc::oclHostMatrixInverse64Bits( const char* aKernelName, double *dpOcl
     clStatus = clReleaseMemObject( mpClmemRightData );
     CHECK_OPENCL( clStatus, "clReleaseMemObject" );
     mpClmemRightData = NULL;
-    clStatus = clReleaseKernel( kernel_solve );
-    CHECK_OPENCL( clStatus, "clReleaseKernel" );
     clStatus = clReleaseMemObject( clpPData );
     CHECK_OPENCL( clStatus, "clReleaseKernel" );
     clStatus = clReleaseMemObject( clpYData );
@@ -2453,20 +2455,23 @@ bool OclCalc::oclHostMatrixInverse32Bits( const char* aKernelName, float *fpOclM
     clStatus = clEnqueueUnmapMemObject( kEnv.mpkCmdQueue, mpClmemLeftData, fpOclMatrixSrc, 0, NULL, NULL );
     CHECK_OPENCL( clStatus, "clEnqueueUnmapMemObject" );
 
-    cl_kernel kernel_solve = clCreateKernel( kEnv.mpkProgram, "oclMatrixSolve", &clStatus );
-    CHECK_OPENCL( clStatus, "clCreateKernel" );
-    clStatus = clSetKernelArg( kernel_solve, 0, sizeof(cl_mem), (void *)&mpClmemLeftData );
+    Kernel* pKernelMatrix = fetchKernel("oclMatrixSolve");
+    if (!pKernelMatrix)
+        return false;
+
+    clStatus = clSetKernelArg(pKernel->mpKernel, 0, sizeof(cl_mem), (void *)&mpClmemLeftData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
-    clStatus = clSetKernelArg( kernel_solve, 1, sizeof(cl_mem), (void *)&mpClmemRightData );
+    clStatus = clSetKernelArg(pKernel->mpKernel, 1, sizeof(cl_mem), (void *)&mpClmemRightData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
-    clStatus = clSetKernelArg( kernel_solve, 2, sizeof(cl_mem), (void *)&clpPData );
+    clStatus = clSetKernelArg(pKernel->mpKernel, 2, sizeof(cl_mem), (void *)&clpPData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
-    clStatus = clSetKernelArg( kernel_solve, 3, sizeof(cl_mem), (void *)&clpYData );
+    clStatus = clSetKernelArg(pKernel->mpKernel, 3, sizeof(cl_mem), (void *)&clpYData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
-    clStatus = clSetKernelArg( kernel_solve, 4, sizeof(cl_mem), (void *)&clpNData );
+    clStatus = clSetKernelArg(pKernel->mpKernel, 4, sizeof(cl_mem), (void *)&clpNData);
     CHECK_OPENCL( clStatus, "clSetKernelArg" );
 
-    clStatus = clEnqueueNDRangeKernel( kEnv.mpkCmdQueue, kernel_solve, 1, NULL, global_work_size, NULL, 0, NULL, NULL );
+    clStatus = clEnqueueNDRangeKernel(
+        kEnv.mpkCmdQueue, pKernel->mpKernel, 1, NULL, global_work_size, NULL, 0, NULL, NULL);
     CHECK_OPENCL( clStatus, "clEnqueueNDRangeKernel" );
     clFinish( kEnv.mpkCmdQueue );
     for ( uint i = 0; i < nDim; i++ )
@@ -2482,8 +2487,6 @@ bool OclCalc::oclHostMatrixInverse32Bits( const char* aKernelName, float *fpOclM
     clStatus = clReleaseMemObject( mpClmemRightData );
     CHECK_OPENCL( clStatus, "clReleaseMemObject" );
     mpClmemRightData = NULL;
-    clStatus = clReleaseKernel( kernel_solve );
-    CHECK_OPENCL( clStatus, "clReleaseKernel" );
     clStatus = clReleaseMemObject( clpPData );
     CHECK_OPENCL( clStatus, "clReleaseKernel" );
     clStatus = clReleaseMemObject( clpYData );
commit c76e4526172681d8abc086dcd87068ad7be1f2b8
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Sep 17 14:59:49 2013 -0400

    Compile kernel when fetching the Kernel instance.
    
    To make the code a bit cleaner.
    
    Change-Id: Id129cea834e950e422e55e6c2504c1f88c5dbeab

diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx
index c468669..ce0f662 100644
--- a/sc/source/core/opencl/openclwrapper.cxx
+++ b/sc/source/core/opencl/openclwrapper.cxx
@@ -152,15 +152,25 @@ int OpenclDevice::setKernelEnv( KernelEnv *envInfo )
     return 1;
 }
 
-Kernel* OpenclDevice::checkKernelName( const char *kernelName )
+Kernel* OpenclDevice::fetchKernel( const char *kernelName )
 {
+    cl_int nStatus;
     for (size_t i = 0, n = gpuEnv.maKernels.size(); i < n; ++i)
     {
         Kernel* pKernel = &gpuEnv.maKernels[i];
         if (!strcasecmp(kernelName, pKernel->mpName))
         {
             printf("found the kernel named %s.\n", kernelName);
-            return pKernel;
+            if (!pKernel->mpKernel && gpuEnv.mpArryPrograms[0])
+            {
+                pKernel->mpKernel = clCreateKernel(gpuEnv.mpArryPrograms[0], kernelName, &nStatus);
+                if (nStatus != CL_SUCCESS)
+                    pKernel->mpKernel = NULL;
+
+                printf("Kernel named '%s' has been compiled\n", kernelName);
+            }
+
+            return pKernel->mpKernel ?  pKernel : NULL;
         }
     }
 
@@ -1000,15 +1010,10 @@ bool OclCalc::oclHostArithmeticOperator64Bits( const char* aKernelName, double *
 {
     cl_int clStatus = 0;
     size_t global_work_size[1];
-    Kernel* pKernel = checkKernelName(aKernelName);
+    Kernel* pKernel = fetchKernel(aKernelName);
     if (!pKernel)
         return false;
 
-    if (!pKernel->mpKernel)
-    {
-        pKernel->mpKernel = clCreateKernel(kEnv.mpkProgram, aKernelName, &clStatus);
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
     clFinish( kEnv.mpkCmdQueue );
     cl_mem clResult = clCreateBuffer( kEnv.mpkContext, CL_MEM_READ_WRITE,
                           nRowSize * sizeof(double), NULL, &clStatus);
@@ -1048,16 +1053,10 @@ bool OclCalc::oclMoreColHostArithmeticOperator64Bits( int nDataSize,int neOpSize
     cl_int clStatus = 0;
     size_t global_work_size[1];
     const char *aKernelName = "oclMoreColArithmeticOperator";
-    Kernel* pKernel = checkKernelName(aKernelName);
+    Kernel* pKernel = fetchKernel(aKernelName);
     if (!pKernel)
         return false;
 
-    if (!pKernel->mpKernel)
-    {
-        pKernel->mpKernel = clCreateKernel(kEnv.mpkProgram, aKernelName, &clStatus);
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
-
     cl_mem clResult = clCreateBuffer( kEnv.mpkContext, CL_MEM_READ_WRITE, nRowSize * sizeof(double), NULL, &clStatus );
     CHECK_OPENCL( clStatus, "clCreateBuffer" );
     clStatus = clSetKernelArg(pKernel->mpKernel, 0, sizeof(cl_mem), (void *)&mpClmemLeftData);
@@ -1095,15 +1094,10 @@ bool OclCalc::oclHostArithmeticStash64Bits( const char* aKernelName, const doubl
     cl_int clStatus = 0;
     size_t global_work_size[1];
     setKernelEnv( &kEnv );
-    Kernel* pKernel = checkKernelName(aKernelName);
+    Kernel* pKernel = fetchKernel(aKernelName);
     if (!pKernel)
         return false;
 
-    if (!pKernel->mpKernel)
-    {
-        pKernel->mpKernel = clCreateKernel( kEnv.mpkProgram, aKernelName, &clStatus );
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
     clFinish( kEnv.mpkCmdQueue );
 
     cl_mem clLeftData = clCreateBuffer( kEnv.mpkContext, (cl_mem_flags) (CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR),
@@ -1149,16 +1143,10 @@ bool OclCalc::oclHostFormulaStash64Bits( const char* aKernelName, const double*
     cl_int clStatus = 0;
     size_t global_work_size[1];
     setKernelEnv( &kEnv );
-    Kernel* pKernel = checkKernelName(aKernelName);
+    Kernel* pKernel = fetchKernel(aKernelName);
     if (!pKernel)
         return false;
 
-    if (!pKernel->mpKernel)
-    {
-        pKernel->mpKernel = clCreateKernel(kEnv.mpkProgram, aKernelName, &clStatus);
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
-
     cl_mem clSrcData   = clCreateBuffer( kEnv.mpkContext, (cl_mem_flags) (CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR),
         nBufferSize * sizeof(double), (void *)dpSrcData, &clStatus );
     CHECK_OPENCL( clStatus, "clCreateBuffer" );
@@ -1205,16 +1193,10 @@ bool OclCalc::oclHostFormulaStatistics64Bits( const char* aKernelName, double *&
 {
     cl_int clStatus = 0;
     size_t global_work_size[1];
-    Kernel* pKernel = checkKernelName(aKernelName);
+    Kernel* pKernel = fetchKernel(aKernelName);
     if (!pKernel)
         return false;
 
-    if (!pKernel->mpKernel)
-    {
-        pKernel->mpKernel = clCreateKernel(kEnv.mpkProgram, aKernelName, &clStatus);
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
-
     cl_mem outputCl = clCreateBuffer( kEnv.mpkContext, CL_MEM_READ_WRITE, size * sizeof(double), NULL, &clStatus );
     CHECK_OPENCL( clStatus, "clCreateBuffer" );
     clStatus = clSetKernelArg(pKernel->mpKernel, 0, sizeof(cl_mem),(void *)&mpClmemSrcData);
@@ -1252,18 +1234,12 @@ bool OclCalc::oclHostFormulaStatistics64Bits( const char* aKernelName, double *&
 bool OclCalc::oclHostFormulaCount64Bits( uint *npStartPos, uint *npEndPos, double *&dpOutput, int nSize )
 {
     const char *cpKernelName = "oclFormulaCount";
-    Kernel* pKernel = checkKernelName(cpKernelName);
+    Kernel* pKernel = fetchKernel(cpKernelName);
     if (!pKernel)
         return false;
 
     cl_int clStatus;
 
-    if (!pKernel->mpKernel)
-    {
-        pKernel->mpKernel = clCreateKernel(kEnv.mpkProgram, cpKernelName, &clStatus);
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
-
     size_t global_work_size[1];
     clStatus = clEnqueueUnmapMemObject( kEnv.mpkCmdQueue, mpClmemStartPos, npStartPos, 0, NULL, NULL );
     CHECK_OPENCL( clStatus, "clEnqueueUnmapMemObject" );
@@ -1310,15 +1286,10 @@ bool OclCalc::oclHostFormulaSumProduct64Bits( double *dpSumProMergeLfData, doubl
     memset(dpOutput,0,nSize);
     const char *cpFirstKernelName = "oclSignedMul";
     const char *cpSecondKernelName = "oclFormulaSumproduct";
-    Kernel* pKernel1 = checkKernelName(cpFirstKernelName);
+    Kernel* pKernel1 = fetchKernel(cpFirstKernelName);
     if (!pKernel1)
         return false;
 
-    if (!pKernel1->mpKernel)
-    {
-        pKernel1->mpKernel = clCreateKernel(kEnv.mpkProgram, cpFirstKernelName, &clStatus);
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
     clStatus = clEnqueueUnmapMemObject( kEnv.mpkCmdQueue, mpClmemMergeLfData, dpSumProMergeLfData, 0, NULL, NULL );
     CHECK_OPENCL( clStatus, "clEnqueueUnmapMemObject" );
     clFinish(kEnv.mpkCmdQueue);
@@ -1348,15 +1319,10 @@ bool OclCalc::oclHostFormulaSumProduct64Bits( double *dpSumProMergeLfData, doubl
     clStatus = clReleaseMemObject( mpClmemMergeRtData );
     CHECK_OPENCL( clStatus, "clReleaseMemObject" );
 
-    Kernel* pKernel2 = checkKernelName(cpSecondKernelName);
+    Kernel* pKernel2 = fetchKernel(cpSecondKernelName);
     if (!pKernel2)
         return false;
 
-    if (!pKernel2->mpKernel)
-    {
-        pKernel2->mpKernel = clCreateKernel(kEnv.mpkProgram, cpSecondKernelName, &clStatus);
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
     cl_mem clpOutput = clCreateBuffer( kEnv.mpkContext, CL_MEM_READ_WRITE, nSize* sizeof(double), NULL, &clStatus );
     CHECK_OPENCL( clStatus, "clCreateBuffer" );
     cl_uint nMatixSize = nFormulaColSize * nFormulaRowSize;
@@ -1576,16 +1542,10 @@ bool OclCalc::oclHostArithmeticOperator32Bits( const char* aKernelName,double *r
     cl_int clStatus = 0;
     size_t global_work_size[1];
 
-    Kernel* pKernel = checkKernelName(aKernelName);
+    Kernel* pKernel = fetchKernel(aKernelName);
     if (!pKernel)
         return false;
 
-    if (!pKernel->mpKernel)
-    {
-        pKernel->mpKernel = clCreateKernel(kEnv.mpkProgram, aKernelName, &clStatus);
-        CHECK_OPENCL( clStatus, "clCreateKernel" );
-    }
-
     cl_mem clResult = clCreateBuffer( kEnv.mpkContext, CL_MEM_READ_WRITE, nRowSize * sizeof(float), NULL, &clStatus );
     CHECK_OPENCL( clStatus, "clCreateBuffer" );
     clStatus = clSetKernelArg(pKernel->mpKernel, 0, sizeof(cl_mem), (void *)&mpClmemLeftData);

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list