McUtils.Extensions

A package for managing extension modules. The existing ExtensionLoader will be moving here, and will be supplemented by classes for dealing with compiled extensions

Members

Examples

Before we can run our examples we should get a bit of setup out of the way. Since these examples were harvested from the unit tests not all pieces will be necessary for all situations.

All tests are wrapped in a test class

class ExtensionsTests(TestCase):

BasicTypeSig

    def test_BasicTypeSig(self):
        sig = FunctionSignature(
            "my_func",
            Argument("num_1", RealType),
            Argument("num_2", RealType, default=5),
            Argument("some_int", IntType)
        )
        self.assertEquals(sig.cpp_signature, "void my_func(double num_1, double num_2, int some_int)")

SOSig

    def test_SOSig(self):
        lib_file = TestManager.test_data('libmbpol.so')
        mbpol = SharedLibraryFunction(lib_file,
                                      FunctionSignature(
                                          "calcpot_",
                                          Argument("nw", PointerType(IntType)),
                                          Argument("energy", PointerType(RealType)),
                                          Argument("coords", ArrayType(RealType))
                                      )
                                      )
        self.assertTrue("SharedLibraryFunction(FunctionSignature(calcpot_(Argument('nw', PointerType(PrimitiveType(int)))" in repr(mbpol))

SharedLibraryFunction

    def test_SharedLibraryFunction(self):
        lib_file = TestManager.test_data('libmbpol.so')
        mbpol = SharedLibraryFunction(lib_file,
                                      FunctionSignature(
                                          "calcpot_",
                                          Argument("nwaters", PointerType(IntType)),
                                          Argument("energy", PointerType(RealType)),
                                          Argument("coords", ArrayType(RealType)),
                                          return_type=None,
                                          defaults={'energy':0}
                                      ),
                                      return_handler=lambda r,kw:SharedLibraryFunction.uncast(kw['energy']) / 627.5094740631
                                      )
        water = np.array([
            [0, 0, 0],
            [1, 0, 0],
            [0, 1, 0]
        ])

        # print(mbpol(nwaters=1, coords=water))
        self.assertGreater(mbpol(nwaters=1, coords=water), .005)

        water = np.array([  # some random structure Mathematica got from who knows where...
            [-0.063259, -0.25268,    0.2621],
            [ 0.74277,   0.26059,    0.17009],
            [-0.67951,  -0.0079118, -0.43219]
        ])

        # print(mbpol(nwaters=1, coords=water))
        self.assertGreater(mbpol(nwaters=1, coords=water), .0006)

        water = np.array([  # some structure from the MBX tests...
            [-0.0044590985, -0.0513425796,  0.0000158138],
            [ 0.9861302114, -0.0745730984,  0.0000054324],
            [-0.1597470923,  0.8967180895, -0.0000164932]
        ])

        # print(mbpol(nwaters=1, coords=water))
        self.assertGreater(mbpol(nwaters=1, coords=water), .001)

SharedLibrary

    def test_SharedLibrary(self):
        lib_file = TestManager.test_data('libmbpol.so')
        mbpol = SharedLibrary(
            lib_file,
            get_pot=dict(
                name='calcpot_',
                nwaters=(int,),
                energy=(float,),
                coords=[float],
                return_type=None,
                defaults={'energy': 0},
                return_handler=lambda r, kw: SharedLibraryFunction.uncast(kw['energy']) / 627.5094740631
            ),
            get_pot_grad = dict(
                name='calcpotg_',
                nwaters=(int,),
                energy=(float,),
                coords=[float],
                grad=[float],
                return_type=None,
                prep_args=lambda kw:[kw.__setitem__('grad', np.zeros(kw['nwaters']*9)), kw][1],
                defaults={'grad':None, 'energy': 0},
                return_handler=lambda r, kw: {
                    'grad':kw['grad'].reshape(-1, 3) / 627.5094740631,
                    'energy':SharedLibraryFunction.uncast(kw['energy']) / 627.5094740631
                }
            )
        )

        water = np.array([
            [0, 0, 0],
            [1, 0, 0],
            [0, 1, 0]
        ])

        # print(mbpol(nwaters=1, coords=water))
        self.assertGreater(mbpol.get_pot_grad(nwaters=1, coords=water)['energy'], .005)
        self.assertEquals(mbpol.get_pot_grad(nwaters=1, coords=water)['grad'].shape, (3, 3))

        water = np.array([  # some random structure Mathematica got from who knows where...
            [-0.063259, -0.25268,    0.2621],
            [ 0.74277,    0.26059,   0.17009],
            [-0.67951,  -0.0079118, -0.43219]
        ])

        # print(mbpol(nwaters=1, coords=water))
        self.assertGreater(mbpol.get_pot_grad(nwaters=1, coords=water)['energy'], .0006)
        self.assertEquals(mbpol.get_pot_grad(nwaters=1, coords=water)['grad'].shape, (3, 3))

        water = np.array([  # some structure from the MBX tests...
            [-0.0044590985, -0.0513425796, 0.0000158138],
            [0.9861302114, -0.0745730984, 0.0000054324],
            [-0.1597470923, 0.8967180895, -0.0000164932]
        ])

        # print(mbpol(nwaters=1, coords=water))
        self.assertGreater(mbpol.get_pot_grad(nwaters=1, coords=water)['energy'], .001)
        self.assertEquals(mbpol.get_pot_grad(nwaters=1, coords=water)['grad'].shape, (3, 3))

FFI

    def test_FFI(self):
        lib_dir = TestManager.test_data('LegacyMBPol')
        mbpol = FFIModule.from_lib(lib_dir, extra_link_args=['-mmacosx-version-min=12.0'])

        water = np.array([
            [0, 0, 0],
            [1, 0, 0],
            [0, 1, 0]
        ])

        # print(mbpol.get_pot_grad(nwaters=1, coords=water))
        self.assertGreater(mbpol.get_pot_grad(nwaters=1, coords=water)['energy'], .005)

        water = np.array([  # some random structure Mathematica got from who knows where...
            [-0.063259, -0.25268,    0.2621],
            [ 0.74277,   0.26059,    0.17009],
            [-0.67951,  -0.0079118, -0.43219]
        ])

        # print(mbpol.get_pot_grad(nwaters=1, coords=water))
        self.assertGreater(mbpol.get_pot_grad(nwaters=1, coords=water)['energy'], .0006)

        water = np.array([  # some structure from the MBX tests...
            [-0.0044590985, -0.0513425796, 0.0000158138],
            [0.9861302114, -0.0745730984, 0.0000054324],
            [-0.1597470923, 0.8967180895, -0.0000164932]
        ])

        # print(mbpol.get_pot_grad(nwaters=1, coords=water))
        self.assertGreater(mbpol.get_pot_grad(nwaters=1, coords=water)['energy'], .001)

FFI_threaded

    def test_FFI_threaded(self): # More detailed testing in test_mbpol.py
        lib_dir = TestManager.test_data('LegacyMBPol')
        mbpol = FFIModule.from_lib(lib_dir,
                                   extra_link_args=['-mmacosx-version-min=12.0']
                                   # , threaded=True
                                   # , recompile=True
                                   )

        from Peeves.Timer import Timer
        waters = np.array([
                              [
                                  [0, 0, 0],
                                  [1, 0, 0],
                                  [0, 1, 0]
                              ],
                              [  # some random structure Mathematica got from who knows where...
                                  [-0.063259, -0.25268, 0.2621],
                                  [0.74277, 0.26059, 0.17009],
                                  [-0.67951, -0.0079118, -0.43219]
                              ],
                              [  # some structure from the MBX tests...
                                  [-0.0044590985, -0.0513425796, 0.0000158138],
                                  [0.9861302114, -0.0745730984, 0.0000054324],
                                  [-0.1597470923, 0.8967180895, -0.0000164932]
                              ]
                          ] * 2500
                          )

        with Timer(tag="Threaded"):
            res = mbpol.get_pot(nwaters=1, coords=waters, threading_var='coords')
            print(np.mean(res))
        # print("="*100)
        # print(waters[0])
        # print(mbpol.get_pot(nwaters=1, coords=waters[0]))
        with Timer(tag="Unthreaded"):
            res = np.array([mbpol.get_pot(nwaters=1, coords=w) for w in waters])
            print(np.mean(res))

Feedback

Examples

Templates

Documentation