Просмотр исходного кода

src: check if there is enough memory available on a node before allocation

  - each driver on initialisation, call the function
    _starpu_memory_manager_init_global_memory() to initialises the
    amount of global memory available on the device

  - starpu_allocate_buffer_on_node() first checks there is enough
    available memory on the node -- by calling
    _starpu_memory_manager_can_allocate_size() -- before doing the
    allocation, otherwise it returns NULL

  - TODO: starpu_malloc() should also call
    _starpu_memory_manager_can_allocate_size() to check if there is
    enough available memory
Nathalie Furmento лет назад: 12
Родитель
Сommit
842b7b131a

+ 52 - 5
src/datawizard/memory_manager.c

@@ -17,15 +17,14 @@
 #include <starpu.h>
 #include <common/config.h>
 #include <datawizard/memory_manager.h>
+#include <starpu_cuda.h>
+#include <starpu_opencl.h>
 
 static size_t global_size[STARPU_MAXNODES];
 static size_t used_size[STARPU_MAXNODES];
 
 int _starpu_memory_manager_init()
 {
-#ifdef STARPU_DEVEL
-#  warning use hwloc to get global size
-#endif
 	int i;
 
 	for(i=0 ; i<STARPU_MAXNODES ; i++)
@@ -36,10 +35,58 @@ int _starpu_memory_manager_init()
 	return 0;
 }
 
+void _starpu_memory_manager_init_global_memory(unsigned node, enum starpu_archtype type, int devid, struct _starpu_machine_config *config)
+{
+	switch (type)
+	{
+#ifdef STARPU_USE_CPU
+	case STARPU_CPU_WORKER:
+	{
+		global_size[node] = _starpu_cpu_get_global_mem_size(node, config);
+		break;
+	}
+#endif
+
+#ifdef STARPU_USE_CUDA
+	case STARPU_CUDA_WORKER:
+	{
+		global_size[node] = starpu_cuda_get_global_mem_size(devid);
+		break;
+	}
+#endif /* STARPU_USE_CUDA */
+
+#ifdef STARPU_USE_OPENCL
+	case STARPU_OPENCL_WORKER:
+	{
+		global_size[node] = starpu_opencl_get_global_mem_size(devid);
+		break;
+	}
+#endif /* STARPU_USE_OPENCL */
+
+	default:
+		STARPU_ABORT();
+	}
+
+	_STARPU_DEBUG("Global size for node %d (%d) is %ld\n", node, type, (long)global_size[node]);
+}
+
 int _starpu_memory_manager_can_allocate_size(size_t size, unsigned node)
 {
-	used_size[node] += size;
-	return 1;
+	if (global_size[node] == 0)
+	{
+		// We do not have information on the available size, let's suppose it is going to fit
+		used_size[node] += size;
+		return 1;
+	}
+	else if (used_size[node] + size < global_size[node])
+	{
+		used_size[node] += size;
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
 }
 
 void _starpu_memory_manager_deallocate_size(size_t size, unsigned node)

+ 7 - 0
src/datawizard/memory_manager.h

@@ -19,6 +19,7 @@
 
 #include <starpu.h>
 #include <common/config.h>
+#include <core/workers.h>
 
 /**
  * Initialises the memory manager
@@ -26,6 +27,12 @@
 int _starpu_memory_manager_init();
 
 /**
+ * Initialises the global memory for the given node
+ *
+ */
+void _starpu_memory_manager_init_global_memory(unsigned node, enum starpu_archtype type, int devid, struct _starpu_machine_config *config);
+
+/**
  * Indicates if memory can be allocated on the given node
  *
  * @param size amount of memory to allocate

+ 24 - 1
src/drivers/cpu/driver_cpu.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2010-2013  Université de Bordeaux 1
  * Copyright (C) 2010  Mehdi Juhoor <mjuhoor@gmail.com>
- * Copyright (C) 2010, 2011, 2012  Centre National de la Recherche Scientifique
+ * Copyright (C) 2010-2013  Centre National de la Recherche Scientifique
  * Copyright (C) 2011  Télécom-SudParis
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -28,6 +28,7 @@
 #include <core/debug.h>
 #include "driver_cpu.h"
 #include <core/sched_policy.h>
+#include <datawizard/memory_manager.h>
 
 #ifdef STARPU_HAVE_HWLOC
 #include <hwloc.h>
@@ -197,6 +198,7 @@ int _starpu_cpu_driver_init(struct starpu_driver *d)
 	int devid = cpu_worker->devid;
 
 	_starpu_worker_init(cpu_worker, _STARPU_FUT_CPU_KEY);
+	_starpu_memory_manager_init_global_memory(cpu_worker->memory_node, STARPU_CPU_WORKER, cpu_worker->devid, cpu_worker->config);
 
 	snprintf(cpu_worker->name, sizeof(cpu_worker->name), "CPU %d", devid);
 	snprintf(cpu_worker->short_name, sizeof(cpu_worker->short_name), "CPU %d", devid);
@@ -359,3 +361,24 @@ int _starpu_run_cpu(struct starpu_driver *d)
 
 	return 0;
 }
+
+size_t _starpu_cpu_get_global_mem_size(int devid, struct _starpu_machine_config *config)
+{
+#if defined(STARPU_HAVE_HWLOC)
+        unsigned int depth_node;
+	struct starpu_machine_topology *topology = &config->topology;
+        depth_node = hwloc_get_type_depth(topology->hwtopology, HWLOC_OBJ_NODE);
+
+#ifdef HWLOC_API_VERSION
+	return hwloc_get_obj_by_depth(topology->hwtopology, depth_node, devid)->memory.total_memory;
+#else
+	return hwloc_get_obj_by_depth(topology->hwtopology, depth_node, devid)->attr->node.memory_kB * 1024;
+#endif
+
+#else /* STARPU_HAVE_HWLOC */
+#ifdef STARPU_DEVEL
+#  warning use sysinfo when available to get global size
+#endif
+	return 0;
+#endif
+}

+ 4 - 1
src/drivers/cpu/driver_cpu.h

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  * Copyright (C) 2010  Université de Bordeaux 1
- * Copyright (C) 2010, 2012  Centre National de la Recherche Scientifique
+ * Copyright (C) 2010, 2012, 2013  Centre National de la Recherche Scientifique
  *
  * StarPU is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -21,6 +21,7 @@
 #include <common/config.h>
 #include <core/jobs.h>
 #include <core/task.h>
+#include <core/workers.h>
 
 #include <core/perfmodel/perfmodel.h>
 #include <common/fxt.h>
@@ -41,4 +42,6 @@ void _starpu_cpu_discover_devices(struct _starpu_machine_config *config);
 } while (0)
 #endif /* !STARPU_USE_CPU */
 
+size_t _starpu_cpu_get_global_mem_size(int devid, struct _starpu_machine_config *config);
+
 #endif //  __DRIVER_CPU_H__

+ 3 - 0
src/drivers/cuda/driver_cuda.c

@@ -29,6 +29,7 @@
 #ifdef HAVE_CUDA_GL_INTEROP_H
 #include <cuda_gl_interop.h>
 #endif
+#include <datawizard/memory_manager.h>
 
 #ifdef STARPU_SIMGRID
 #include <core/simgrid.h>
@@ -404,6 +405,8 @@ int _starpu_cuda_driver_init(struct starpu_driver *d)
 	init_context(devid);
 #endif
 
+	_starpu_memory_manager_init_global_memory(args->memory_node, STARPU_CUDA_WORKER, args->devid, args->config);
+
 	/* one more time to avoid hacks from third party lib :) */
 	_starpu_bind_thread_on_cpu(args->config, args->bindid);
 

+ 3 - 0
src/drivers/opencl/driver_opencl.c

@@ -28,6 +28,7 @@
 #include "driver_opencl.h"
 #include "driver_opencl_utils.h"
 #include <common/utils.h>
+#include <datawizard/memory_manager.h>
 
 #ifdef STARPU_SIMGRID
 #include <core/simgrid.h>
@@ -529,6 +530,8 @@ int _starpu_opencl_driver_init(struct starpu_driver *d)
 	/* one more time to avoid hacks from third party lib :) */
 	_starpu_bind_thread_on_cpu(args->config, args->bindid);
 
+	_starpu_memory_manager_init_global_memory(args->memory_node, STARPU_OPENCL_WORKER, args->devid, args->config);
+
 	args->status = STATUS_UNKNOWN;
 
 #ifdef STARPU_SIMGRID