Skip to content

Commit

Permalink
Merge pull request #38 from gregvw/ml-python
Browse files Browse the repository at this point in the history
Consolidate PyROL updates
  • Loading branch information
aj463 authored Jul 30, 2024
2 parents c4bbff6 + d101ba6 commit 7416b87
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 74 deletions.
44 changes: 28 additions & 16 deletions packages/rol/pyrol/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,28 @@ TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_BINDER_SUPPRESS_ERRORS
"Enable the suppress errors option of Binder."
OFF )

TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_BINDER_USE_ONE_FILE
PYROL_USE_ONE_FILE
"Enable the use of one file by Binder."
OFF )

TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_BINDER_CMAKE_ERROR
PYROL_CMAKE_ERROR
"Stop the configuration if binder fails."
"Stop the configuration if Binder fails."
ON )

TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_BINDER_VERBOSE
PYROL_B_VERBOSE
"Increase the verbosity of binder"
"Increase the verbosity of Binder"
OFF )

TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_ENABLE_BINDER_UPDATE
PYROL_UPDATE_GENERATED_SRC
"Enable the update of the generated source files with Binder."
OFF )

SET(PYROL_BINDER_NUM_FILES "100" CACHE STRING "Maximum number of generated files by Binder.")

MESSAGE("-- PYTHON_EXECUTABLE:")
IF(NOT DEFINED ${PYTHON_EXECUTABLE})
find_program(PYTHON_EXECUTABLE
Expand Down Expand Up @@ -130,6 +137,7 @@ list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm")
list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeB")
list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeE")
list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeG")
list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeP")
list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeU")
list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeB/pqn")
list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeG/augmentedlagrangian/")
Expand Down Expand Up @@ -266,15 +274,6 @@ IF (PYROL_GENERATE_SRC)
endforeach()
endforeach()


#list(REMOVE_DUPLICATES PyROL_all_include_files_without_dir)
#list(REMOVE_ITEM PyROL_all_include_files_without_dir "")

#list(REMOVE_DUPLICATES PyROL_all_include_files_with_dir)
#list(REMOVE_ITEM PyROL_all_include_files_with_dir "")

#MESSAGE("PyROL_all_include_files_with_dir = ${PyROL_all_include_files_with_dir}")

SET(CONTENTS "")
FOREACH(line IN LISTS all_include_dirs)
SET(CONTENTS "${CONTENTS}${line}\n")
Expand All @@ -295,7 +294,7 @@ IF (PYROL_GENERATE_SRC)

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src)

file (GLOB PyROLPyFiles2 "${CMAKE_CURRENT_BINARY_DIR}/python/*.py")
list (APPEND PyROLPyFiles ${PyROLPyFiles2})

Expand All @@ -307,7 +306,12 @@ IF (PYROL_GENERATE_SRC)
list(APPEND BINDER_OPTIONS ${binder_include_name})
list(APPEND BINDER_OPTIONS --root-module pyrol)
list(APPEND BINDER_OPTIONS --prefix ${CMAKE_CURRENT_BINARY_DIR}/binder)
list(APPEND BINDER_OPTIONS -max-file-size=1000000)
IF(PYROL_USE_ONE_FILE)
list(APPEND BINDER_OPTIONS -single-file)
ELSE()
list(APPEND BINDER_OPTIONS -max-file-size=1000000)
list(APPEND BINDER_OPTIONS -flat)
ENDIF()
list(APPEND BINDER_OPTIONS --bind Teuchos)
list(APPEND BINDER_OPTIONS --bind ROL)
list(APPEND BINDER_OPTIONS --bind pyrol)
Expand All @@ -317,7 +321,7 @@ IF (PYROL_GENERATE_SRC)
list(APPEND BINDER_OPTIONS --config ${BINDER_CFG})
IF(PYROL_SUPPRESS_ERRORS)
list(APPEND BINDER_OPTIONS --suppress-errors)
ENDIF()
ENDIF()
list(APPEND BINDER_OPTIONS --)
IF(TPL_ENABLE_CUDA)
list(APPEND BINDER_OPTIONS -x cuda --cuda-host-only)
Expand All @@ -337,10 +341,18 @@ IF (PYROL_GENERATE_SRC)

message("BINDER_OPTIONS='${BINDER_OPTIONS}'")

IF(NOT PYROL_USE_ONE_FILE)
MATH(EXPR NUMBER_FILE "${PYROL_BINDER_NUM_FILES}")

foreach(index RANGE 0 ${NUMBER_FILE})
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/binder/pyrol_${index}.cpp "")
endforeach()
ENDIF()

EXECUTE_PROCESS(COMMAND
${PyROL_BINDER_EXECUTABLE} ${BINDER_OPTIONS}
RESULT_VARIABLE STATUS
OUTPUT_VARIABLE OUTPUT_BINDER
OUTPUT_VARIABLE OUTPUT_BINDER
)

if(STATUS AND NOT STATUS EQUAL 0)
Expand All @@ -351,7 +363,7 @@ IF (PYROL_GENERATE_SRC)
message("BINDER FAILED: ${STATUS}")
endif()
else()
message(STATUS "BINDER SUCCESS:")
message(STATUS "BINDER SUCCESS:")
message("${OUTPUT_BINDER}")
endif()

Expand Down
69 changes: 69 additions & 0 deletions packages/rol/pyrol/example/pytorch/rosenbrock_torch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from TorchVectors import TensorVector
from TorchObjectives import TorchObjective

from pyrol import getCout, Objective, Problem, Solver
from pyrol.vectors import NumPyVector

from pyrol.pyrol.Teuchos import ParameterList

import numpy as np
import time
import torch


class RosenbrockObjective(TorchObjective):

def __init__(self):
super().__init__()
self.alpha = 100

def torch_value(self, x):
# return torch.sum(self.alpha*(x[::2]**2 - x[1::2])**2 + (x[::2] - 1)**2)
return torch.sum(self.alpha*(x[:-1]**2 - x[1:])**2 + (x[:-1] - 1)**2)


def build_parameter_list():
params = ParameterList()
params['General'] = ParameterList()
params['General']['Output Level'] = 1
params['Step'] = ParameterList()
params['Step']['Trust Region'] = ParameterList()
params['Step']['Trust Region']['Subproblem Solver'] = 'Truncated CG'
params['Status Test'] = ParameterList()
params['Status Test']['Iteration Limit'] = 10000

return params


def main():

torch.set_default_dtype(torch.float64)

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
#device = torch.device('cpu')

start = time.time()
n = int(1e2)
print(device)
x = torch.empty(n, requires_grad=False, device=device)
x[ ::2] = -1.2
x[1::2] = 1.0
x = TensorVector(x)

objective = RosenbrockObjective()
g = x.clone()

stream = getCout()

problem = Problem(objective, x, g)
# problem.checkDerivatives(True, stream)

params = build_parameter_list()
solver = Solver(problem, params)
solver.solve(stream)
print(f"Solve time: {time.time() - start}\n")

print(g.torch_object.device)

if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions packages/rol/pyrol/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ ROL_ENABLE_PYROL = "ON"
PYROL_ENABLE_BINDER = "OFF"
PYROL_PIP_INSTALL = "ON"
CMAKE_INSTALL_RPATH="$ORIGIN/lib64;$ORIGIN/lib;$ORIGIN;@loader_path/lib64;@loader_path/lib;@loader_path"
CMAKE_INTERPROCEDURAL_OPTIMIZATION="OFF"
2 changes: 2 additions & 0 deletions packages/rol/pyrol/python/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import importlib

from . getTypeName import getTypeName, getDefaultScalarType, ROL_classes, ROL_members
from pyrol.pyrol.Teuchos import ParameterList


__version__ = '0.1.0'
def version():
Expand Down
44 changes: 41 additions & 3 deletions packages/rol/pyrol/python/getTypeName.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,57 @@ def new_method(self, *args, **kwargs):
return cls_method(self, *args, **kwargs)
return new_method

def withTrackingConstructor(cls):
def _decorator23(value_method):
def value(*args):
if len(args) == 2:
x, tol = args
return value_method(x.get_1(), x.get_2(), tol)
elif len(args) == 3:
u, z, tol = args
return value_method(u, z, tol)
else:
raise ArgumentError("Unexcepted number of arguments")
return value


def _decorator34(value_method):
def value(*args):
if len(args) == 3:
c, x, tol = args
return value_method(c, x.get_1(), x.get_2(), tol)
elif len(args) == 4:
c, u, z, tol = args
return value_method(c, u, z, tol)
raise ArgumentError("Unexcepted number of arguments")
return value


def withTrackingConstructor(cls_name, cls):
class newCls(cls):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self._tracked_constructor_args = []

track(self, *args, **kwargs)
method_names = [m for m in dir(cls) if callable(getattr(cls, m))]

for name in method_names:
if name.startswith('add'):
setattr(newCls, name, tracking_method(getattr(cls, name)))

if cls_name.find('Objective_SimOpt') == 0:
self.value = _decorator23(self.value)
elif cls_name.find('Constraint_SimOpt') == 0:
self.value = _decorator34(self.value)

return newCls


ROL_members = {}
for cls_name, cls_obj in inspect.getmembers(sys.modules['pyrol.pyrol.ROL']):
if inspect.isclass(cls_obj):
cls_obj = withTrackingConstructor(cls_obj)
cls_obj = withTrackingConstructor(cls_name, cls_obj)
trackedTypes.append(cls_obj)
setattr(sys.modules['pyrol.pyrol.ROL'], cls_name, cls_obj)
ROL_members[cls_name] = (cls_obj, inspect.isclass(cls_obj))
Expand All @@ -57,3 +87,11 @@ def getTypeName(class_name, scalar_type=getDefaultScalarType()):
return ROL_classes[i][1]
print("Warning: Unknown type \"{}\", the function returns None.".format(class_name))
return None


def getTypeName2(class_name):
for i in range(0, len(ROL_classes)):
if ROL_classes[i][0].lower().find(class_name.lower()) == 0:
return ROL_classes[i][1]
print("Warning: Unknown type \"{}\", the function returns None.".format(class_name))
return None
4 changes: 3 additions & 1 deletion packages/rol/pyrol/scripts/PyROL_RCP.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
-function ROL::TypeB::AlgorithmFactory
-function ROL::TypeE::AlgorithmFactory
-function ROL::TypeG::AlgorithmFactory
-function ROL::TypeP::AlgorithmFactory
-function ROL::TypeU::AlgorithmFactory
-class ROL::ConstraintAssembler

Expand All @@ -101,7 +102,7 @@
+trampoline_member_function_binder ROL::Vector::clone customClone

+include_for_namespace ROL::PyROL <PyROL_ETI_helper.hpp>
-namespace ROL::details
# -namespace ROL::details

#################################################r
# std library #
Expand Down Expand Up @@ -156,6 +157,7 @@
-class std::vector<Teuchos::RCP>
+class std::vector<int>
+class std::vector<double>
+class std::vector<std::vector<double>>
+class std::vector<ROL::TimeStamp<double>>

-namespace __gnu_cxx
19 changes: 8 additions & 11 deletions packages/rol/pyrol/scripts/create_sdist
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
# to and then run from the directory containing the ROL repository.


# - Users of this script should check that the variables below are defined
# - Users of this script should check that the variables below are defined
# properly.
##############################################################################
TRILINOS_VERSION="14.5"
TRILINOS_VERSION="15.1"
REPO_NAME="ROL-Trilinos"

LLVM_PREFIX=$(spack location -i llvm)
LLVM_VERSION=$(echo ${LLVM_PREFIX} | awk -F[\-\-] '{print $5}')
GCC_PREFIX=$(spack location -i gcc)
##############################################################################

## Other prerequisites:
## Other prerequisites:

# * Binder (after the changes on its smart_holder branch)
if [ ! command -v binder &> /dev/null ]
Expand Down Expand Up @@ -54,23 +54,20 @@ cmake -G Ninja \
-D CMAKE_INSTALL_PREFIX:PATH=install \
./${REPO_NAME} -B./build

## Step 2: Run Binder.
make -C build

## Step 3: Create the reduced tarball.
## Step 2: Create the reduced tarball.
make package_source -C build
TARBALL_NAME="trilinos-${TRILINOS_VERSION}-Source"

## Step 4: Unpack the reduced tarball.
## Step 3: Unpack the reduced tarball.
[ -d ${TARBALL_NAME} ] && rm -rf ${TARBALL_NAME}
tar -zxf "build/${TARBALL_NAME}.tar.gz"
mv ${TARBALL_NAME} pyrol
mv ${TARBALL_NAME} pyrol

## Step 5: Create an SDist from the tarball.
## Step 4: Create an SDist from the tarball.
python -m pipx run build --sdist pyrol
cp -r pyrol/dist/* .

## Step 6: Clean up.
## Step 5: Clean up.
rm -rf build
rm -rf ${REPO_NAME}/packages/rol/pyrol/binder
rm -rf pyrol
Loading

0 comments on commit 7416b87

Please sign in to comment.