Add a unit test to be used to test parallelised calculations in Calc

Currently only tests SUMIFS.

Yes, it would be nice if some of the already existing unit tests would
work for this need, too. But there are various reasons wny not. Also,
don't want to interfere in ongoing work by others.

Change-Id: Ie9008a4a1a8c26eff4f2ab0bc91294b2239f0ae1
This commit is contained in:
Tor Lillqvist 2017-08-10 17:13:45 +03:00
parent f75f116a22
commit 244f605312
6 changed files with 301 additions and 1 deletions

View file

@ -0,0 +1,108 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# 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/.
#
$(eval $(call gb_CppunitTest_CppunitTest,sc_parallelism))
$(eval $(call gb_CppunitTest_add_exception_objects,sc_parallelism, \
sc/qa/unit/parallelism \
))
$(eval $(call gb_CppunitTest_use_externals,sc_parallelism, \
boost_headers \
$(call gb_Helper_optional,OPENCL,clew) \
mdds_headers \
))
$(eval $(call gb_CppunitTest_use_libraries,sc_parallelism, \
basegfx \
comphelper \
cppu \
cppuhelper \
drawinglayer \
editeng \
for \
forui \
i18nlangtag \
msfilter \
oox \
sal \
salhelper \
sax \
sc \
scqahelper \
sfx \
sot \
svl \
svt \
svx \
svxcore \
test \
tk \
tl \
ucbhelper \
unotest \
utl \
vcl \
xo \
))
$(eval $(call gb_CppunitTest_set_include,sc_parallelism,\
-I$(SRCDIR)/sc/source/ui/inc \
-I$(SRCDIR)/sc/source/core/inc \
-I$(SRCDIR)/sc/inc \
$$(INCLUDE) \
))
$(eval $(call gb_CppunitTest_use_sdk_api,sc_parallelism))
$(eval $(call gb_CppunitTest_use_ure,sc_parallelism))
$(eval $(call gb_CppunitTest_use_vcl,sc_parallelism))
$(eval $(call gb_CppunitTest_use_components,sc_parallelism,\
basic/util/sb \
chart2/source/chartcore \
chart2/source/controller/chartcontroller \
comphelper/util/comphelp \
configmgr/source/configmgr \
dbaccess/util/dba \
embeddedobj/util/embobj \
eventattacher/source/evtatt \
filter/source/config/cache/filterconfig1 \
forms/util/frm \
framework/util/fwk \
i18npool/util/i18npool \
linguistic/source/lng \
oox/util/oox \
package/source/xstor/xstor \
package/util/package2 \
sax/source/expatwrap/expwrap \
scaddins/source/analysis/analysis \
scaddins/source/datefunc/date \
sc/util/sc \
sc/util/scfilt \
sfx2/util/sfx \
sot/util/sot \
svl/util/svl \
svtools/util/svt \
svx/util/svx \
svx/util/svxcore \
toolkit/util/tk \
ucb/source/core/ucb1 \
ucb/source/ucp/file/ucpfile1 \
ucb/source/ucp/tdoc/ucptdoc1 \
uui/util/uui \
unotools/util/utl \
unoxml/source/rdf/unordf \
unoxml/source/service/unoxml \
xmloff/util/xo \
))
$(eval $(call gb_CppunitTest_use_configuration,sc_parallelism))
# vim: set noet sw=4 ts=4:

View file

@ -96,6 +96,7 @@ $(eval $(call gb_Module_add_subsequentcheck_targets,sc,\
JunitTest_sc_unoapi_6 \
JunitTest_sc_unoapi_7 \
CppunitTest_sc_opencl_test \
CppunitTest_sc_parallelism \
CppunitTest_sc_anchor_test \
CppunitTest_sc_annotationshapeobj \
CppunitTest_sc_outlineobj \

View file

@ -138,6 +138,7 @@ public:
static bool switchOpenCLDevice(const OUString& rDeviceId, bool bAutoSelect, bool bForceEvaluation = false);
// This is intended to be called from opencl-test.cxx only
static void enableOpenCL_UnitTestsOnly();
static void disableOpenCL_UnitTestsOnly();
static void getOpenCLDeviceInfo(sal_Int32& rDeviceId, sal_Int32& rPlatformId);
#endif
virtual ScMatrixRef inverseMatrix(const ScMatrix& rMat) = 0;

181
sc/qa/unit/parallelism.cxx Normal file
View file

@ -0,0 +1,181 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
#include <sal/config.h>
#include <test/bootstrapfixture.hxx>
#include <rtl/strbuf.hxx>
#include <osl/file.hxx>
#include "scdll.hxx"
#include <sfx2/app.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/sfxmodelfactory.hxx>
#include <svl/stritem.hxx>
#include "helper/qahelper.hxx"
#include "calcconfig.hxx"
#include "interpre.hxx"
#include "docsh.hxx"
#include "postit.hxx"
#include "patattr.hxx"
#include "scitems.hxx"
#include "document.hxx"
#include "cellform.hxx"
#include "drwlayer.hxx"
#include "userdat.hxx"
#include "formulacell.hxx"
#include "formulagroup.hxx"
#include <svx/svdpage.hxx>
using namespace css;
using namespace css::uno;
class ScParallelismTest : public ScBootstrapFixture
{
public:
ScParallelismTest();
virtual void setUp() override;
virtual void tearDown() override;
void getNewDocShell(ScDocShellRef& rDocShellRef);
void testSUMIFS();
CPPUNIT_TEST_SUITE(ScParallelismTest);
CPPUNIT_TEST(testSUMIFS);
CPPUNIT_TEST_SUITE_END();
private:
ScDocument *m_pDoc;
ScDocShellRef m_xDocShell;
};
ScParallelismTest::ScParallelismTest()
: ScBootstrapFixture( "/sc/qa/unit/data" )
{
}
void ScParallelismTest::setUp()
{
test::BootstrapFixture::setUp();
ScDLL::Init();
getNewDocShell(m_xDocShell);
m_pDoc = &m_xDocShell->GetDocument();
sc::FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly();
}
void ScParallelismTest::tearDown()
{
if(m_xDocShell.is())
{
m_xDocShell->DoClose();
m_xDocShell.clear();
}
test::BootstrapFixture::tearDown();
}
void ScParallelismTest::getNewDocShell( ScDocShellRef& rDocShellRef )
{
rDocShellRef = new ScDocShell(
SfxModelFlags::EMBEDDED_OBJECT |
SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
}
void ScParallelismTest::testSUMIFS()
{
m_pDoc->InsertTab(0, "1");
m_pDoc->SetValue(0, 0, 0, 1001);
/*E1*/ m_pDoc->SetFormula(ScAddress(5, 0, 0),
"=$F$2+$F$3",
formula::FormulaGrammar::GRAM_ENGLISH);
/*F1*/ m_pDoc->SetFormula(ScAddress(6, 0, 0),
"=SUM($F$2:$F$3)",
formula::FormulaGrammar::GRAM_ENGLISH);
for (auto i = 1; i < 1000; i++)
{
/*A*/ m_pDoc->SetValue(0, i, 0, i/10 + 1000);
/*B*/ m_pDoc->SetValue(1, i, 0, i%10);
/*C*/ m_pDoc->SetValue(2, i, 0, i%5);
/*F*/ m_pDoc->SetValue(5, i, 0, i%17 + i%13);
/*L*/ m_pDoc->SetValue(11, i, 0, i%10);
/*M*/ m_pDoc->SetValue(12, i, 0, i%5);
}
for (auto i = 1; i < 1000; i++)
{
// For instance P389 will contain the formula:
// =SUMIFS($F$2:$F$1000; $A$2:$A$1000; A$1; $B$2:$B$1000; $L389; $C$2:$C$1000; $M389)
// In other words, it will sum those values in F2:1000 where the A value matches A1 (1001),
// the B value matches L389 and the C value matches M389. (There should be just one such
// value, so the formula is actually simply used to pick out that single value from the F
// column where A,B,C match. Silly, but that is how SUMIFS is used in some corners of the
// real world, apparently.)
/*P*/ m_pDoc->SetFormula(ScAddress(15, i, 0),
"=SUMIFS($F$2:$F$1000; "
"$A$2:$A$1000; A$1; "
"$B$2:$B$1000; $L" + OUString::number(i+1) + "; "
"$C$2:$C$1000; $M" + OUString::number(i+1) +
")",
formula::FormulaGrammar::GRAM_NATIVE_UI);
}
m_xDocShell->DoHardRecalc();
#if 1
OUString sFormula;
std::cerr << "A1=" << m_pDoc->GetValue(0, 0, 0) << std::endl;
m_pDoc->GetFormula(5, 0, 0, sFormula);
std::cerr << "E1=" << "\"" << sFormula << "\"=" << m_pDoc->GetValue(5, 0, 0) << std::endl;
m_pDoc->GetFormula(6, 0, 0, sFormula);
std::cerr << "F1=" << "\"" << sFormula << "\"=" << m_pDoc->GetValue(6, 0, 0) << std::endl;
std::cerr << " A,B,C F L,M" << std::endl;
for (auto i = 1; i < 30; i++)
{
std::cerr <<
i+1 << ": " <<
m_pDoc->GetValue(0, i, 0) << "," <<
m_pDoc->GetValue(1, i, 0) << "," <<
m_pDoc->GetValue(2, i, 0) << " " <<
m_pDoc->GetValue(5, i, 0) << " " <<
m_pDoc->GetValue(11, i, 0) << "," <<
m_pDoc->GetValue(12, i, 0) << " \"";
m_pDoc->GetFormula(15, i, 0, sFormula);
std::cerr << sFormula << "\": \"" <<
m_pDoc->GetString(15, i, 0) << "\": " <<
m_pDoc->GetValue(15, i, 0) << std::endl;
}
#endif
for (auto i = 1; i < 1000; i++)
{
OString sMessage = "At row " + OString::number(i+1);
CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(sMessage.getStr(), m_pDoc->GetValue(5, 10+i%10, 0), m_pDoc->GetValue(15, i, 0), 1e-10);
}
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScParallelismTest);
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -369,6 +369,13 @@ void FormulaGroupInterpreter::enableOpenCL_UnitTestsOnly()
ScInterpreter::SetGlobalConfig(aConfig);
}
void FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly()
{
std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
officecfg::Office::Common::Misc::UseOpenCL::set(false, batch);
batch->commit();
}
#endif
} // namespace sc

View file

@ -340,7 +340,9 @@ FormulaLogger::GroupScope FormulaLogger::enterGroup(
// Get the file name if available.
const SfxObjectShell* pShell = rDoc.GetDocumentShell();
const SfxMedium* pMedium = pShell->GetMedium();
OUString aName = pMedium->GetURLObject().GetLastName();
OUString aName;
if (pMedium)
aName = pMedium->GetURLObject().GetLastName();
if (aName.isEmpty())
aName = "-"; // unsaved document.