File: testThreads.py

package info (click to toggle)
rdkit 201809.1%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 123,688 kB
  • sloc: cpp: 230,509; python: 70,501; java: 6,329; ansic: 5,427; sql: 1,899; yacc: 1,739; lex: 1,243; makefile: 445; xml: 229; fortran: 183; sh: 123; cs: 93
file content (122 lines) | stat: -rw-r--r-- 4,871 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import sys
from rdkit import Chem
from rdkit import six
import threading
import multiprocessing

# this just tests some threading stuff to ensure it doesn't crash with python
#  releasing the GIL smarts are recursive...
ref_sdf = '\n     RDKit          3D\n\n 22 23  0  0  1  0  0  0  0  0999 V2000\n   -6.1917   -1.9517    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -5.0664   -1.3009    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -3.9401   -1.9499    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -2.8148   -1.2991    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -1.6885   -1.9483    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0\n   -0.5632   -1.2973    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -0.5642    0.0027    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -1.6905    0.6517    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -1.6916    1.9517    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0\n   -2.8158    0.0009    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -3.9422    0.6501    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -5.0685    1.2991    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0\n    0.5632   -1.9465    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0\n    1.6885   -1.2955    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    1.6874    0.0046    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0\n    2.8148   -1.9447    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    3.9401   -1.2936    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    3.9391    0.0064    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    5.0644    0.6572    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    6.1907    0.0082    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    6.1917   -1.2918    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    5.0664   -1.9429    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n  1  2  1  0\n  2  3  1  0\n  3  4  1  0\n  4 10  2  0\n  4  5  1  0\n  5  6  2  0\n  6  7  1  0\n  6 13  1  0\n  7  8  2  0\n  8  9  1  0\n  8 10  1  0\n 10 11  1  0\n 11 12  3  0\n 13 14  1  0\n 14 15  2  0\n 14 16  1  0\n 16 17  1  0\n 17 22  1  0\n 17 18  2  0\n 18 19  1  0\n 19 20  2  0\n 20 21  1  0\n 21 22  2  0\nM  END'
ref_mol = Chem.MolFromMolBlock(ref_sdf)

core_smarts = '[#6]-!@[#6]-!@[#8]-!@[#6]:1:[#6](-!@[#6]#!@[#7]):[#6](-!@[#7]):[#6]:[#6](-!@[#7]-!@[#6](-!@[#6]-!@[#6]:2:[#6]:[#6]:[#6]:[#6]:[#6]:2)=!@[#8]):[#7]:1'
if ref_mol is None:
  raise ValueError('Bad ref structure')
core_mol = Chem.MolFromSmarts(core_smarts)
if core_mol is None:
  raise ValueError('Bad core structure')

expected = {}


def runner(func, args):
  if args:
    res = getattr(ref_mol, func)(args)
  else:
    res = getattr(ref_mol, func)()
  if func in expected:
    assert res == expected[func], "Got %r expected %r" % (ers, expected[func])
  return res


funcs = ["GetSubstructMatch", "GetSubstructMatches", "HasSubstructMatch"]

# get the expected results from the non-thread version
for func in funcs:
  expected[func] = runner(func, core_mol)

nthreads = int(multiprocessing.cpu_count() * 100 / 4)  # 100 threads per cpu
threads = []
for i in range(0, nthreads):
  for func in funcs:
    t = threading.Thread(target=runner, args=(func, core_mol))
    t.start()
    threads.append(t)
  t = threading.Thread(target=runner, args=("ToBinary", None))
  t.start()
  threads.append(t)
for t in threads:
  t.join()


def LogError():
  i = 0
  while 1:
    if i == 10:
      break
    i += 1
    Chem.LogErrorMsg(str(i) + ":: My dog has fleas")


def LogWarning():
  i = 0
  while 1:
    if i == 10:
      break
    i += 1
    Chem.LogWarningMsg(str(i) + ":: All good boys to fine")

  # this spews a ton of logging info...
  #  that is all intermingled...


if 0:
  nthreads = int(multiprocessing.cpu_count())
  threads = []
  for i in range(0, nthreads):
    for func in funcs:
      if i % 2 == 0:
        t = threading.Thread(target=LogError)
      else:
        t = threading.Thread(target=LogWarning)
      t.start()
      threads.append(t)
    t = threading.Thread(target=LogWarning)
    t.start()
    threads.append(t)

  for t in threads:
    t.join()

Chem.WrapLogs()

err = sys.stderr
stringio = sys.stderr = six.StringIO()

# now the errors should be synchronized...
nthreads = int(multiprocessing.cpu_count())
threads = []
for i in range(0, nthreads):
  for func in funcs:
    if i % 2 == 0:
      t = threading.Thread(target=LogError)
    else:
      t = threading.Thread(target=LogWarning)
    t.start()
    threads.append(t)
  t = threading.Thread(target=LogWarning)
  t.start()
  threads.append(t)

for t in threads:
  t.join()
sys.stderr = err

stringio = sys.stderr = six.StringIO()
LogWarning()
LogError()
sys.stderr = err
assert "WARNING" in stringio.getvalue()
assert "ERROR" in stringio.getvalue()
assert stringio.getvalue().count("WARNING") == 10
assert stringio.getvalue().count("ERROR") == 10