1 //
2 //  Copyright (C) 2004-2018 Greg Landrum and Rational Discovery LLC
3 //
4 //   @@ All Rights Reserved @@
5 //  This file is part of the RDKit.
6 //  The contents are covered by the terms of the BSD license
7 //  which is included in the file license.txt, found at the root
8 //  of the RDKit source tree.
9 //
10 
11 #include <RDGeneral/test.h>
12 #include <iostream>
13 #include <RDGeneral/Invariant.h>
14 #include <RDGeneral/RDLog.h>
15 #include <RDGeneral/utils.h>
16 
17 #include <GraphMol/RDKitBase.h>
18 #include <GraphMol/SmilesParse/SmilesParse.h>
19 #include <GraphMol/SmilesParse/SmilesWrite.h>
20 #include <GraphMol/FileParsers/FileParsers.h>
21 #include <GraphMol/FileParsers/MolSupplier.h>
22 
23 #include <GraphMol/ForceFieldHelpers/FFConvenience.h>
24 #include <GraphMol/ForceFieldHelpers/MMFF/AtomTyper.h>
25 #include <GraphMol/ForceFieldHelpers/MMFF/Builder.h>
26 #include <GraphMol/ForceFieldHelpers/MMFF/MMFF.h>
27 #include <ForceField/ForceField.h>
28 #include <ForceField/MMFF/Params.h>
29 #include <GraphMol/DistGeomHelpers/Embedder.h>
30 #include <GraphMol/Substruct/SubstructMatch.h>
31 #include <boost/math/special_functions/round.hpp>
32 
33 using namespace RDKit;
34 #ifdef RDK_TEST_MULTITHREADED
35 namespace {
runblock_mmff(const std::vector<ROMol * > & mols)36 void runblock_mmff(const std::vector<ROMol *> &mols) {
37   for (auto mol : mols) {
38     ForceFields::ForceField *field = MMFF::constructForceField(*mol);
39     TEST_ASSERT(field);
40     field->initialize();
41     field->minimize(1);
42     delete field;
43   }
44 }
45 }  // namespace
46 #include <thread>
47 #include <future>
testMMFFMultiThread()48 void testMMFFMultiThread() {
49   BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
50   BOOST_LOG(rdErrorLog) << "    Test MMFF multithreading" << std::endl;
51 
52   std::string pathName = getenv("RDBASE");
53   pathName += "/Code/GraphMol/ForceFieldHelpers/MMFF/test_data";
54   SDMolSupplier suppl(pathName + "/bulk.sdf");
55   unsigned int count = 24;
56   std::vector<std::vector<ROMol *>> mols;
57   for (unsigned int i = 0; i < count; ++i) {
58     mols.emplace_back();
59   }
60 
61   while (!suppl.atEnd() && mols.size() < 100) {
62     ROMol *mol = nullptr;
63     try {
64       mol = suppl.next();
65       for (unsigned int i = 0; i < count; ++i) {
66         if (i == 0) {
67           mols[i].push_back(mol);
68         } else {
69           mols[i].push_back(new ROMol(*mol));
70         }
71       }
72     } catch (...) {
73       continue;
74     }
75   }
76 
77   std::vector<std::future<void>> tg;
78 
79   std::cerr << "processing" << std::endl;
80   for (unsigned int i = 0; i < count; ++i) {
81     std::cerr << " launch :" << i << std::endl;
82     std::cerr.flush();
83     tg.emplace_back(std::async(std::launch::async, runblock_mmff, mols[i]));
84   }
85   for (auto &fut : tg) {
86     fut.get();
87   }
88   std::cerr << "done" << std::endl;
89   for (unsigned int i = 0; i < count; ++i)
90     for (auto *mol : mols[i]) {
91       delete mol;
92     }
93 
94   BOOST_LOG(rdErrorLog) << "  done" << std::endl;
95 }
96 
97 #endif
98 //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
99 //
100 //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
main()101 int main() {
102   RDLog::InitLogs();
103   // we get a ton of warnings here about missing Hs... disable them
104   boost::logging::disable_logs("rdApp.warning");
105 
106 #ifdef RDK_TEST_MULTITHREADED
107   testMMFFMultiThread();
108 #endif
109 }
110