The individual invocations within a work group will be executed "in parallel". The main purpose of the distinction between work group count and local size is that the different compute shader invocations within a work group can communicate through a set of shared variables and special functions. Invocations in different work groups (within the same compute shader dispatch) cannot effectively communicate. Not without potentially deadlocking the system.
You can assign work groups for your compute shader for some limited communication, but in general the compute shader runs in parallel without a defined order, trying to force it to run sequentially would slow down the GPU to a crawl since it's power comes from running all operations in parallel.
In this case the solution is to write to a separate texture from the one your reading from, if you don't the operation will be undefined and could cause all sorts of problems because of said multitasking.
If your input is a 1024x1024x30 3d texture for instance, and you wish to process it in sequence along the w coordinate then you create a 1024x1024x30 output image, then use glDispatchCompute to define as many workgroups as you need, or define layout(local_size_x = X, local_size_y = Y, local_size_z = Z) in; in your compute shader
#version 430
#define width 1024
#define height 1024
layout(local_size_x=width, local_size_y=height) in;
uniform layer;
writeonly uniform image3D output;
uniform sampler3D input;
// gl_GlobalInvocationID is a uvec3 variable giving the global ID of the thread,
// gl_LocalInvocationID is the local index within the work group, and
// gl_WorkGroupID is the work group's index
void main() {
ivec2 pos = ivec3(gl_GlobalInvocationID.xy, layer);
imageStore(output, pos, texture3D(input, pos));
}
Code is untested but should hopefully be enough to get you started. If you create more than one workgroup you have to multiply that with the layout used in the shader to get the total size of the work space.
for (int layer = 0; layer < 30; layer++) {
glUniform1i(layerPosition, layer);
glDispatchCompute(1,1,1); // X: 1*1024 Y: 1*1024 Z: 1*1
}
Remember to not write to the same texture your reading from, so if you want to use the previous computations result you will need to swap textures around between executions as well.