Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Move jobpy to Docker images #3741

Merged
merged 13 commits into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/blender/benchmark/benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def __init__(self):
main_scene_file = pathlib.Path(self.blender_task_path)
main_scene_file /= self.SCENE_FILE_NAME
task_def.main_scene_file = str(main_scene_file)
task_def.main_program_file = self.ENVIRONMENT_CLASS().main_program_file
task_def.resources.add(str(main_scene_file.resolve()))


Expand Down
4 changes: 0 additions & 4 deletions apps/blender/blenderenvironment.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from os import path
from typing import Dict

from apps.core import nvgpu
from apps.core.nvgpu import get_devices
from golem.core.common import get_golem_path
from golem.docker.environment import DockerEnvironment
from golem.docker.image import DockerImage
from golem.environments.environment import SupportStatus, UnsupportReason
Expand All @@ -13,8 +11,6 @@ class BlenderEnvironment(DockerEnvironment):
DOCKER_IMAGE = "golemfactory/blender"
DOCKER_TAG = "1.5"
ENV_ID = "BLENDER"
APP_DIR = path.join(get_golem_path(), 'apps', 'blender')
SCRIPT_NAME = "docker_blendertask.py"
SHORT_DESCRIPTION = "Blender (www.blender.org)"


Expand Down
8 changes: 3 additions & 5 deletions apps/blender/task/blenderrendertask.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,13 @@ def __init__(self):
RendererDefaults.__init__(self)
self.output_format = "EXR"

self.main_program_file = BlenderEnvironment().main_program_file
self.min_subtasks = 1
self.max_subtasks = 100
self.default_subtasks = 6


class BlenderNVGPUDefaults(BlenderDefaults):
def __init__(self):
super().__init__()
self.main_program_file = BlenderNVGPUEnvironment().main_program_file
pass


class PreviewUpdater(object):
Expand Down Expand Up @@ -458,7 +455,8 @@ def query_extra_data(self, perf_index: float, num_cores: int = 0,
"path_root": self.main_scene_dir,
"start_task": start_task,
"total_tasks": self.total_tasks,
"crops": crops
"crops": crops,
"script_filepath": "/golem/scripts/job.py",
}

subtask_id = self.create_subtask_id()
Expand Down
14 changes: 1 addition & 13 deletions apps/core/task/coretask.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,6 @@ def __init__(self,
# pylint: disable=not-callable
self.environment = self.ENVIRONMENT_CLASS()

# src_code stuff
self.main_program_file = self.environment.main_program_file
try:
with open(self.main_program_file, "r") as src_file:
src_code = src_file.read()
except OSError as err:
logger.warning("Wrong main program file: %s", err)
src_code = ""

# docker_images stuff
if task_definition.docker_images:
self.docker_images = task_definition.docker_images
Expand All @@ -151,7 +142,7 @@ def __init__(self,
concent_enabled=task_definition.concent_enabled,
)

Task.__init__(self, th, src_code, task_definition)
Task.__init__(self, th, task_definition)

self.total_tasks = total_tasks
self.last_task = 0
Expand Down Expand Up @@ -343,7 +334,6 @@ def _new_compute_task_def(self, subtask_id, extra_data,
ctd['task_id'] = self.header.task_id
ctd['subtask_id'] = subtask_id
ctd['extra_data'] = extra_data
ctd['src_code'] = self.src_code
ctd['performance'] = perf_index
if self.docker_images:
ctd['docker_images'] = [di.to_dict() for di in self.docker_images]
Expand Down Expand Up @@ -507,7 +497,6 @@ def __init__(self,
self.root_path = dir_manager.root_path
self.dir_manager = dir_manager
self.owner = owner
self.src_code = ""
self.environment = None

def build(self):
Expand All @@ -532,7 +521,6 @@ def build_minimal_definition(cls, task_type: CoreTaskTypeInfo, dictionary):
definition.compute_on = dictionary.get('compute_on', 'cpu')
definition.resources = set(dictionary['resources'])
definition.subtasks_count = int(dictionary['subtasks_count'])
definition.main_program_file = task_type.defaults.main_program_file
return definition

@classmethod
Expand Down
5 changes: 0 additions & 5 deletions apps/core/task/coretaskstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class TaskDefaults(object):

def __init__(self):
self.output_format = ""
self.main_program_file = ""
self.min_subtasks = 1
self.max_subtasks = 50
self.default_subtasks = 20
Expand Down Expand Up @@ -45,7 +44,6 @@ def __init__(self):

self.subtasks_count = 0
self.optimize_total = False
self.main_program_file = ""
self.output_file = ""
self.task_type = None
self.name = ""
Expand Down Expand Up @@ -94,9 +92,6 @@ def __setstate__(self, state):
setattr(self, key, attributes[key])

def is_valid(self):
if not path.exists(self.main_program_file):
return False, "Main program file does not exist: {}".format(
self.main_program_file)
return self._check_output_file(self.output_file)

@staticmethod
Expand Down
4 changes: 0 additions & 4 deletions apps/dummy/benchmark/benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
from pathlib import Path

from apps.core.benchmark.benchmarkrunner import CoreBenchmark
from apps.dummy.dummyenvironment import DummyTaskEnvironment
from apps.dummy.task.dummytask import DummyTask
from apps.dummy.task.dummytaskstate import DummyTaskDefinition, \
DummyTaskDefaults
from apps.dummy.task.verifier import DummyTaskVerifier
from golem.core.common import get_golem_path
from golem.verificator.verifier import SubtaskVerificationState

APP_DIR = join(get_golem_path(), 'apps', 'dummy')


class DummyTaskBenchmark(CoreBenchmark):
def __init__(self):
Expand All @@ -27,7 +24,6 @@ def __init__(self):
td.out_file_basename = td.out_file_basename

td.task_id = str(uuid.uuid4())
td.main_program_file = DummyTaskEnvironment().main_program_file
td.resources = {join(self.dummy_task_path, "in.data")}
td.add_to_resources()

Expand Down
9 changes: 2 additions & 7 deletions apps/dummy/dummyenvironment.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
from os import path

from golem.core.common import get_golem_path
from golem.docker.environment import DockerEnvironment


class DummyTaskEnvironment(DockerEnvironment):
DOCKER_IMAGE = "golemfactory/base"
DOCKER_TAG = "1.3"
DOCKER_IMAGE = "golemfactory/dummy"
DOCKER_TAG = "1.0"
ENV_ID = "DUMMYPOW"
APP_DIR = path.join(get_golem_path(), 'apps', 'dummy')
SCRIPT_NAME = "docker_dummytask.py"
SHORT_DESCRIPTION = "Dummy task (example app calculating proof-of-work " \
"hash)"
5 changes: 5 additions & 0 deletions apps/dummy/resources/images/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM golemfactory/base:1.3

MAINTAINER Golem Tech <tech@golem.network>

COPY scripts/ /golem/scripts/
1 change: 1 addition & 0 deletions apps/dummy/task/dummytask.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def _extra_data(self, perf_index=0.0) -> ComputeTaskDef:
"result_size": self.task_definition.result_size,
"result_file": self.__get_result_file_name(subtask_id),
"subtask_data_size": sbs,
"script_filepath": "/golem/scripts/job.py",
}

return self._new_compute_task_def(subtask_id,
Expand Down
14 changes: 0 additions & 14 deletions golem/docker/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from golem.docker.image import DockerImage
from golem.environments.environment import (Environment, SupportStatus,
UnsupportReason)
from golem.resource.dirmanager import find_task_script


@enforce.runtime_validation()
Expand All @@ -22,9 +21,6 @@ def __init__(self, tag=None, image_id=None, additional_images: List[DockerImage]
else DockerImage(self.DOCKER_IMAGE, tag=tag)
Environment.__init__(self)

self.main_program_file = find_task_script(self.APP_DIR,
self.SCRIPT_NAME)

self.docker_images = [image]
if additional_images:
self.docker_images += additional_images
Expand Down Expand Up @@ -82,16 +78,6 @@ def DOCKER_TAG(cls):
def ENV_ID(cls):
pass

@property
@abc.abstractmethod
def APP_DIR(cls):
pass

@property
@abc.abstractmethod
def SCRIPT_NAME(cls):
pass

@property
@abc.abstractmethod
def SHORT_DESCRIPTION(cls):
Expand Down
25 changes: 4 additions & 21 deletions golem/docker/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


# pylint:disable=too-many-instance-attributes
class DockerJob(object):
class DockerJob:
STATE_NEW = "new"
STATE_CREATED = "created" # container created by docker
STATE_RUNNING = "running" # docker container running
Expand Down Expand Up @@ -52,16 +52,13 @@ class DockerJob(object):
"OUTPUT_DIR": OUTPUT_DIR
}

# Name of the script file, relative to WORK_DIR
TASK_SCRIPT = "job.py"

# Name of the parameters file, relative to WORK_DIR
PARAMS_FILE = "params.json"

# pylint:disable=too-many-arguments
def __init__(self,
image: DockerImage,
script_src: str,
script_filepath: str,
parameters: Dict,
resources_dir: str,
work_dir: str,
Expand All @@ -82,7 +79,7 @@ def __init__(self,
raise TypeError('Incorrect image type: {}. '
'Should be: DockerImage'.format(type(image)))
self.image = image
self.script_src = script_src
self.script_filepath = script_filepath
self.parameters = parameters if parameters else {}

self.parameters.update(self.PATH_PARAMS)
Expand Down Expand Up @@ -124,23 +121,16 @@ def _prepare(self):
with open(params_file_path, "w") as params_file:
json.dump(self.parameters, params_file)

# Save the script in work_dir/TASK_SCRIPT
task_script_path = self._get_host_script_path()
with open(task_script_path, "wb") as script_file:
script_file.write(bytearray(self.script_src, "utf-8"))

# Setup volumes for the container
client = local_client()

host_cfg = client.create_host_config(**self.host_config)

# The location of the task script when mounted in the container
container_script_path = self._get_container_script_path()
self.container = client.create_container(
image=self.image.name,
volumes=self.volumes,
host_config=host_cfg,
command=[container_script_path],
command=[self.script_filepath],
working_dir=self.WORK_DIR,
environment=self.environment,
)
Expand Down Expand Up @@ -182,9 +172,6 @@ def __enter__(self):
def __exit__(self, exc_type, exc_value, traceback):
self._cleanup()

def _get_host_script_path(self):
return os.path.join(self.work_dir, self.TASK_SCRIPT)

def _get_host_params_path(self):
return os.path.join(self.work_dir, self.PARAMS_FILE)

Expand All @@ -210,10 +197,6 @@ def _host_dir_chmod(dst_dir, mod):

return prev_mod

@staticmethod
def _get_container_script_path():
return posixpath.join(DockerJob.WORK_DIR, DockerJob.TASK_SCRIPT)

@staticmethod
def get_absolute_resource_path(relative_path):
return posixpath.join(DockerJob.RESOURCES_DIR,
Expand Down
4 changes: 1 addition & 3 deletions golem/docker/task_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ class DockerTaskThread(TaskThread):

def __init__(self, # pylint: disable=too-many-arguments
docker_images: List[Union[DockerImage, Dict, Tuple]],
src_code: str,
extra_data: Dict,
dir_mapping: DockerDirMapping,
timeout: int,
Expand All @@ -84,7 +83,6 @@ def __init__(self, # pylint: disable=too-many-arguments
if not docker_images:
raise AttributeError("docker images is None")
super().__init__(
src_code=src_code,
extra_data=extra_data,
res_path=str(dir_mapping.resources),
tmp_path=str(dir_mapping.temporary),
Expand Down Expand Up @@ -190,7 +188,7 @@ def _run_docker_job(self) -> Optional[int]:

params = dict(
image=self.image,
script_src=self.src_code,
script_filepath=self.extra_data['script_filepath'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why script_filepath is part of extra_data ?
As far as I know, in extra_data are all parameters needed inside docker container. script_filepath is used only as command to run docker, so we don't need to pass it to params.json.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is a slight abuse of extra_data, but there were no better alternatives at the time. Ideally src_code from ctd would be replaced with script_filepath (or even better with some environment config dict, e.g. to include argv as well) but this requires changes to Golem-Messages so this will be done separately.

parameters=self.extra_data,
resources_dir=str(self.dir_mapping.resources),
work_dir=str(self.dir_mapping.work),
Expand Down
8 changes: 0 additions & 8 deletions golem/environments/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ def __init__(self):
" without any additional requirements."

self.accept_tasks = False
# Check if tasks can define the source code
self.allow_custom_main_program_file = False
self.main_program_file = None

def check_support(self) -> SupportStatus:
""" Check if this environment is supported on this machine
Expand Down Expand Up @@ -111,11 +108,6 @@ def get_min_accepted_performance(cls) -> float:

return step * MinPerformanceMultiplier.get()

def get_source_code(self):
if self.main_program_file and path.isfile(self.main_program_file):
with open(self.main_program_file) as f:
return f.read()

@classmethod
def run_default_benchmark(cls, save=False):
logger = logging.getLogger('golem.task.benchmarkmanager')
Expand Down
5 changes: 0 additions & 5 deletions golem/task/benchmarkmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,6 @@ def on_success(performance):

@staticmethod
def _validate_task_state(task_state):
td = task_state.definition
if not os.path.exists(td.main_program_file):
logger.error("Main program file does not exist: {}".format(
td.main_program_file))
return False
return True

def run_benchmark_for_env_id(self, env_id, callback, errback):
Expand Down
2 changes: 0 additions & 2 deletions golem/task/localcomputer.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def run(self) -> None:
self.start_time = time.time()
self._prepare_tmp_dir()
self._prepare_resources(self.resources) # makes a copy

if not self.compute_task_def:
ctd = self.get_compute_task_def()
else:
Expand Down Expand Up @@ -186,7 +185,6 @@ def _get_task_thread(self, ctd: ComputeTaskDef) -> DockerTaskThread:
)
return DockerTaskThread(
ctd['docker_images'],
ctd['src_code'],
ctd['extra_data'],
dir_mapping,
0,
Expand Down
2 changes: 0 additions & 2 deletions golem/task/taskbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ def __init__(self, ctd=None, **kwargs):

def __init__(self,
header: dt_tasks.TaskHeader,
src_code: str,
task_definition: TaskDefinition) -> None:
self.src_code = src_code
self.header = header
self.task_definition = task_definition

Expand Down
Loading